Http://www.raywenderlich.com/76024/swift-table-view-animations-tutorial-drop-cards
Standard table view is a powerful and flexible way to render data, and in most cases your app uses some form of table view. However, one drawback is that you can't make too many customizations, and your app will drown in thousands of similar apps.
In order to not use the same table view, we can use some animations to make your app more dazzling. Take a look at the Google + app, which animates the card from the edge. If you have not read it, please download download it here (free)! You can also look at the design guidelines that Google publishes at the I/O conference. It contains a number of examples and tips on how to use animations.
Begin
Download the start item and open it in Xcode 6. In its storyboard there is a Uitableviewcontroller subclass Mainviewcontroller and UITableViewCell subclass Cardtableviewcell. Model objects are memeber classes that encapsulate the information for each member of the team. The data comes from a JSON file in the local resource bundle.
To run the program, the effect is as follows:
The simplest of animations
Use file\new\file ..., rotate ios\source\swiftfile , file name tipincellanimator.swift , then click Create.
Edit the contents of the file as:
Import UIKit class Tipincellanimator { //placeholder for things to come--only fades class func animate(cell:uitableviewcell) { let View = Cell.contentview View.layer.opacity = 0.1 UIView. Animatewithduration(1.4) { View.layer.opacity = 1 } } } |
The class has only one method with a cell, which sets the cell's contentview transparency to 0.1, and then changes the transparency to 1.0 for a period of 1.4 seconds.
Triggering animations
Open Mainviewcontroller.swift to add the following methods:
override func tableview ( Tableview uitableview , Willdisplaycell Cell uitableviewcell , forrowatindexpath indexpath: ) { Tipincellanimator.animate ( cell |
This method is one of the methods in the uitableviewdelegate protocol . It is called before the cell is rendered. In this method we call the Animate method of Tipincellanimator.
Run the program, scroll the table, and the cell will render an fade-in animation effect:
Rotating
Open the tipincellanimator.swiftand modify the content to:
Import UIKit Import Quartzcore //1 class Tipincellanimator { class func animate(cell:uitableviewcell) { let View = Cell.contentview let rotationdegrees: cgfloat = -15.0 let Rotationradians: cgfloat = rotationdegrees * (cgfloat (m_pi)/180.0) let offset = cgpointmake(--- ) var starttransform = catransform3didentity //2 Starttransform = catransform3drotate(catransform3didentity, Rotationradians, 0.0, 0.0, 1.0) //3 Starttransform = catransform3dtranslate(starttransform, Offset.x, Offset.y, 0.0 ) //4 //5 View.layer.transform = starttransform View.layer.opacity = 0.8 //6 UIView. Animatewithduration(0.4) { View.layer.transform = catransform3didentity View.layer.opacity = 1 } } } |
The animation time is 0.4 seconds, the entry effect is more complex, will present a rotation effect. The core of the code above is the Starttransform variable, and returns to its original state at the end of the animation.
1. First you need to import quartzcore so that we can use the core animation animation.
2. Define an identity transform, which means doing nothing. This is the default transform for this view.
3. Call catransform3drotate to achieve a-15-degree (counter-clockwise) rotation. The axis of rotation is 0.0, 0.0, 1.0(respectively, the x, Y, Z axis), which rotates on the z-axis.
4. In addition to the simple rotation, we also made a translation.
5. Set the rotated and panned transform to the transform of the view.
6. Change the state of the view from Starttransform to the default transform.
The effect shown above is as follows:
Note that you are animating on a child view of a cell, not a cell. Rotating cells directly can cause some unexpected effects, such as shaking or cutting off a portion of a cell. Use the cell's contentview to represent that the cell is all child views.
Not all properties support animations, and the list of animatableproperties in Core animationprogramming Guide lists the properties that support animations.
Run the program to see the effect when the table is rendered.
Swift Refactoring
One of the first o-c versions of this tutorial is worth mentioning, and it will ensure that only starttransform is evaluated once. In the preceding code, each call to the animate () method causes Starttransform to be re-assigned. So how does this happen in Swift?
One way is to declare a storage property. This property is obtained by calling a closure calculation.
One wayis to use the immutable stored property, which is computed by calling a closure.
Modify the tipincellanimator.swift content as follows:
Import UIKit Import Quartzcore Let Tipincellanimatorstarttransform:catransform3d = { let rotationdegrees: cgfloat = -15.0 let Rotationradians: cgfloat = rotationdegrees * (cgfloat (m_pi)/180.0) let offset = cgpointmake(--- ) var starttransform = catransform3didentity Starttransform = catransform3drotate(catransform3didentity, Rotationradians, 0.0, 0.0, 1.0) Starttransform = catransform3dtranslate(starttransform, Offset.x, Offset.y, 0.0) return Starttransform }() class Tipincellanimator { class func animate(cell:uitableviewcell) { let View = Cell.contentview View.layer.transform = tipincellanimatorstarttransform View.layer.opacity = 0.8 UIView. Animatewithduration(0.4) { View.layer.transform = catransform3didentity View.layer.opacity = 1 } } } |
Note that the code that created the Starttransform is now placed in the storage properties Tipincellanimatorstarttransform. And we don't define this property in a way that defines the Getter method (which causes each call to the getter method to create a transform). We assign a default value to this property by means of a closure + (). A pair of empty parentheses indicates that the closure is forced to be called, and the return value of the closure is passed to this property. This detail is discussed in the "initializing" chapter of the Apple's swift official tutorial. Please refer to "Setting default values for properties with closures or functions".
Use animations in moderation
Although the effect of animation is very good, but it can not be used without restraint. If the abuse of sound effects and animations once made you suffer, you should be aware of the consequences of being overly dependent on effects!
In this project, just use the effect when the cell first renders-when the table scrolls from top to bottom. When the table rolls up from the bottom, the cell does not need to use effects.
We need to store which cells have been displayed so that no effects are used for the second display. Here, we use a Swift Dictionary object.
Open Mainviewcontroller.swift to add a property:
var didanimatecell: [nsindexpath: Bool] = [:] |
A Dictionary object is defined, key is nsindexpaths type, and the value is Bools type. Then modify TableView (Tableview:,willdisplaycell:, Forrowatindexpath:) The method is:
override func tableview ( tableview: uitableview , Willdisplaycell cell: uitableviewcell , forrowatindexpath indexpath: nsindexpath ) { if didanimatecell[indexpath] = = Nil | | Didanimatecell[indexpath]! == false { Didanimatecell[indexpath] = true Tipincellanimator.animate(cell) } } |
We determine whether the cell's index path already exists in the Didanimatecell dictionary. If it does not exist, this is the first time the cell is displayed; then we will perform the cell animation and set the Indexpath to the dictionary. If there is, nothing is done.
To run the program, pull up the scrolling table and you will see the cell animations:
Swift Table View Animation Tutorial: Drop-in Cards