Create your own grid-based photo browsing app with collection views!
更新说明：原文作者 Brandon Trebitowski，现 Richard Turton 已将内容升级为 Swift 和 iOS 8。
UICollectionReusableView来创建一个新的header。这个类和collection view cell（事实上，cell就是继承这个类）很像，它但主要用于像header或footer的地方。
iOS\Cocoa Touch\Objective-C class template， 点击
MainStoryboard.storyboard，在左侧的Scene Inspector找到collection view。打开其Attributes Inspector 并在Accessories中选中
Collection Reusable View自动被加入了Collection View的下方。点击选中
Collection Reusable View，就可以进行编辑了。
拖一个label到header view中，然后居中放置。调整Font 为System 32.0大小，然后在对齐菜单中设置它水平且垂直居中，然后更新它的frame：
选中header view，在indetity inspector中设置它的
Background为 90% Write，然后设置Identifier为
- The kind parameter is supplied by the layout object and indicates which sort of supplementary view is being asked for.
- UICollectionElementKindSectionHeader is a supplementary view kind belonging to the flow layout. By checking that box in the storyboard to add a section header, you told the flow layout that it needs to start asking for these views. There is also a UICollectionElementKindSectionFooter, which you’re not currently using. If you don’t use the flow layout, you don’t get header and footer views for free like this.
- The header view is dequeued using the identifier added in the storyboard. This works just like cell dequeuing. The label’s text is then set to the relevant search term.
- An assert is placed here to make it clear to other developers (including future you!) that you’re not expecting to be asked for anything other than a header view.
现在已经可以真正的运行了。你会发现UI差不多已经完成了。如果你测试多次搜索，不同的结果集将会被新的header完美区分。作为额外收获，尝试转动设备 - 看看布局如何，包括headwe，是不是很完美 :]
Of course, black and white cabbages are what you’d expect from this search?
In this final section of the tutorial you will learn some ways to interact with collection view cells. You’ll take two different approaches. The first will display a larger version of the image. The second will demonstrate how to support multiple selection in order to share images.
在接下来的部分，你会学习到几种和collection view cell交互的方式。你将来实现两种效果，第一个是显示一张大图。第二种则是弹出共享图片的多种方式。
Collection views can animate changes to their layout. Your first task is to show a larger version of a photo when it is tapped.
- largePhotoIndexPath is an optional that will hold the index path of the tapped photo, if there is one.
- Whenever this property gets updated, the collection view needs to be updated. a didSet property observer is the safest place to manage this. There may be two cells that need reloading, if the user has tapped one cell then another, or just one if the user has tapped the first cell, then tapped it again to shrink.
- performBatchUpdates will animate any changes to the collection view performed inside the block. You want it to reload the affected cells.
- Once the animated update has finished, it’s a nice touch to scroll the enlarged cell to the middle of the screen
“What enlarged cell?”, I hear you asking. You’ll get to that in a minute!
点击一个cell会让collection view选中它。你想知道一个cell被选中，所以你能给它设置 largeIndexPath 属性，但你并不想真正的选中它，因为它会让你困惑当你做多个选择时。
UICollectionViewDelegate。 Collection view问它的delegate是否要选择一个cell。 还在
这个方法非常简单。如果所点的cell已经是大图了，设置 largePhotoIndexPath 为 nil。否则设为index path。 它的didSet方法会被调用，然后重新加载受影响的Cell。
sizeForItemAtIndexPath flow layout代理方法，替换为以下代码：
You’ve added the code highlighted in the comments. This calculates the size of the cell to fill as much of the collection view as possible whilst maintaining its aspect ratio.
Main.storyboard然后拖一个activity indicator到collection view cell的image view上。打开Attributes inspector中，设置Style为
Large White然后选 中
Hides When Stopped。使用
打开assistant editor，按住control拖动activity indicator 到
- Always stop the activity spinner – you could be reusing a cell that was previously loading an image
- This part is as before – if you’re not looking at the large photo, just set the thumbnail and return
- If the large image is already loaded, set it and return
- By this point, you want the large image, but it doesn’t exist yet. Set the thumbnail image and start the spinner going. The thumbnail will stretch until the download is complete
- Ask for the large image from Flickr. This loads the image asynchronously and has a completion block
- The load has finished, so stop the spinner
- If there was an error or no photo was loaded, there’s not much you can do.
- Check that the large photo index path hasn’t changed while the download was happening, and retrieve whatever cell is currently in use for that index path (it may not be the original cell, since scrolling could have happened) and set the large image.
Build and run, perform a search and tap a nice-looking photo – it grows to fill the screen, and the other cells move around to make space!
再次运行，执行一次搜索，然后找一张好看的照片点击下 - 它会慢慢的填充整个屏幕，其它的Cell都向一边跑去。
You look bigger to him as well.
再次点击这个cell，或者移动下点击其它Cell，你不再需要写代码，coolection view和 layout 自动帮你完成了余下的工作！
Your final task for this tutorial is to let the user select multiple photos and share them with a friend. The process for multi-selection on a collection view is very similar to that of a table view. The only trick is to tell the collection view to allow multiple selection.
- The user taps the Share button to tell the UICollectionView to allow multi- selection and set the sharing property to YES.
- The user taps multiple photos that they want to share, adding them to an array.
- The user taps the Share button again, which brings up the sharing interface.
- When the user finishes sharing the images or taps Cancel, the photos are deselected and the collection view goes back to single selection mode.
First, add the following code in FlickrPhotosViewController.swift:
The selectedPhotos array will keep track of the photos the user has selected, and the shareTextLabel will provide feedback to the user on how many photos have been selected. You will call updateSharedPhotoCount to keep shareTextLabel up to date.
Next, (also in FlickrPhotosViewController.swift) create the property that will hold the sharing state:
sharing is a Bool with another property observer, similar to largePhotoIndexPath above. In this observer, you toggle the multiple selection status of the collection view, clear any existing selection, and empty the selected photos array. You also update the bar button items to include and update the label added above.
Open Main.storyboard and drag a UIBarButtonItem to the right of the navigation bar above the collection view controller. In the Attributes Inspector, set the Identifier to Action to give it the familiar sharing icon. Open the assistant editor, making sure FlickrPhotosViewController.swift is open, and control-drag from the bar button into the class to create a new action. Call the action share:
Fill in the action method as shown:
At the moment, all this method does is toggle the sharing state, kicking off all the changes in the property observer method added earlier.
You actually want to allow the user to select cells now, so update shouldSelectItemAtIndexPath to take this into account. Add the following code to the top of the method:
This will allow selection in sharing mode.
Implement the delegate method to add selected photos to the shared photos array and update the label:
And remove them when the cell is deselected (tapped again):
Build and run, and perform a search. Tap the share button to go into sharing mode and select different photos. The label will update and the selected cells will get a fetching Wenderlich Green border.
I don’t know what I was expecting this search to show up, but it wasn’t this
If you tap the share button again, everything just gets deselected, and you go back into non-sharing mode, where tapping a single photo enlarges it.
Of course, this share button isn’t terribly useful unless there’s actually a way to share the photos! Replace the TODO comment in your share method with the following code:
First, this code creates an array of UIImage objects from the FlickrPhoto‘s thumbnails. The UIImage array is much more convenient, as we can simply pass it to a UIActivityViewController. The UIActivityViewController will show the user any image sharing services or actions available on the device: iMessage, Mail, Print, etc. You simply present your UIActivityViewController from within a popover (because this is an iPad app), and let the user take care of the rest!
Build and run, enter sharing mode, select some photos and hit the share button again. Your share dialog will appear!
Note: Testing exclusively on a simulator? You will find the simulator has far fewer sharing options than on device. If you are having trouble confirming that your share screen is properly sharing your images, try the Save (x) Images option. Whether on device or on simulator, this will save the selected images to Photos app, where you can review them to ensure everything worked.
Here is the complete project that you developed in the tutorial series.
Congratulations, you have finished creating your very own stylish Flickr photo browser, complete with a cool UICollectionView based grid view!
In the process, you learned how to make custom UICollectionViewCells, create headers with UICollectionReusableView, detect when rows are tapped, implement multi-cell selection, and much more!
If you have any questions or comments about UICollectionViews or this tutorial, please join the forum discussion below!