collection中cell选中状态下分享图片的快照snapshot
程序员文章站
2022-04-17 18:11:02
...
总结要点
注意:
1:shouldPerformSegue(withIdentifier:sender:) -> bool 方法控制segue的效能
2: let index = selectedIcons.index(where:{$0.icon.name == deSelectedIcon.name})
index(where)条件返回index
3:snapshot生成快照
UIGraphicsBeginImageContext(bounds.size)
if let context = UIGraphicsGetCurrentContext(){
self.layer.render(in:context)
image = UIGraphicsGetImageFromCurrentImageContext()
}
UIGraphicsEndImageContext()
return image
4:let indexPaths = collectionView.indexPathsForSelectedItems返回多个索引,所以在单选的情况下,通过indexPaths.first来获取
5:prepare(for:sender:) 与 shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool连用
6:@IBAction func unwindToHome(segue:UIStoryboardSegue){}//退出exit时link的方法(解除segue)
IconCollectionViewController.swift
IconDetailViewController.swift
IconCollectionViewCell.swift
Icon.swift
UIView+Snapshot.swift
IconCollectionViewController.swift
import UIKit
private let reuseIdentifier = "Cell"
class IconCollectionViewController: UICollectionViewController {
private var iconSet: [Icon] = [ Icon(name: "Candle icon", imageName: "candle", description: "Halloween icons designed by Tania Raskalova.", price: 3.99, isFeatured: false),
Icon(name: "Cat icon", imageName: "cat", description: "Halloween icon designed by Tania Raskalova.", price: 2.99, isFeatured: true),
Icon(name: "dribbble", imageName: "dribbble", description: "Halloween icon designed by Tania Raskalova.", price: 1.99, isFeatured: false),
Icon(name: "Ghost icon", imageName: "ghost", description: "Halloween icon designed by Tania Raskalova.", price: 4.99, isFeatured: false),
Icon(name: "Hat icon", imageName: "hat", description: "Halloween icon designed by Tania Raskalova.", price: 2.99, isFeatured: false),
Icon(name: "Owl icon", imageName: "owl", description: "Halloween icon designed by Tania Raskalova.", price: 5.99, isFeatured: true),
Icon(name: "Pot icon", imageName: "pot", description: "Halloween icon designed by Tania Raskalova.", price: 1.99, isFeatured: false),
Icon(name: "Pumkin icon", imageName: "pumkin", description: "Halloween icon designed by Tania Raskalova.", price: 0.99, isFeatured: false),
Icon(name: "RIP icon", imageName: "rip", description: "Halloween icon designed by Tania Raskalova.", price: 7.99, isFeatured: false),
Icon(name: "Skull icon", imageName: "skull", description: "Halloween icon designed by Tania Raskalova.", price: 8.99, isFeatured: false),
Icon(name: "Sky icon", imageName: "sky", description: "Halloween icon designed by Tania Raskalova.", price: 0.99, isFeatured: false),
Icon(name: "Toxic icon", imageName: "toxic", description: "Halloween icon designed by Tania Raskalova.", price: 2.99, isFeatured: false),
Icon(name: "Book icon", imageName: "ic_book", description: "Colorful icon designed by Marin Begović.", price: 2.99, isFeatured: false),
Icon(name: "Backpack icon", imageName: "ic_backpack", description: "Colorful icon designed by Marin Begović.", price: 3.99, isFeatured: false),
Icon(name: "Camera icon", imageName: "ic_camera", description: "Colorful camera icon designed by Marin Begović.", price: 4.99, isFeatured: false),
Icon(name: "Coffee icon", imageName: "ic_coffee", description: "Colorful icon designed by Marin Begović.", price: 3.99, isFeatured: true),
Icon(name: "Glasses icon", imageName: "ic_glasses", description: "Colorful icon designed by Marin Begović.", price: 3.99, isFeatured: false),
Icon(name: "Icecream icon", imageName: "ic_ice_cream", description: "Colorful icon designed by Marin Begović.", price: 4.99, isFeatured: false),
Icon(name: "Smoking pipe icon", imageName: "ic_smoking_pipe", description: "Colorful icon designed by Marin Begović.", price: 6.99, isFeatured: false),
Icon(name: "Vespa icon", imageName: "ic_vespa", description: "Colorful icon designed by Marin Begović.", price: 9.99, isFeatured: false)]
@IBOutlet weak var shareButton: UIBarButtonItem!
fileprivate var shareEnabled = false
fileprivate var selectedIcons:[(icon:Icon,snapshot:UIImage)] = []
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func shareButtonTapped(_ sender: Any) {
guard shareEnabled else {
// 变更shareEnabled为YES并变更按钮文字为Done
shareEnabled = true
collectionView?.allowsMultipleSelection = true
shareButton.title = "Done"
shareButton.style = UIBarButtonItemStyle.done
return
}
// 确认是使用者至少有选择一个图片
guard selectedIcons.count > 0 else {
let alet = UIAlertController(title: "注意", message: "请选择分享的图片", preferredStyle: .alert)
self.present(alet, animated: true) {
alet.dismiss(animated: true, completion: nil)
}
return
}
// 取得所选图片的快照
let snapshots = selectedIcons.map { $0.snapshot}
// 建立分享用的动态视图控制器
let activityController = UIActivityViewController(activityItems: snapshots, applicationActivities: nil)
///typedef void (^UIActivityViewControllerCompletionWithItemsHandler)(UIActivityType activityType, BOOL completed, NSArray *returnedItems, NSError *activityError);
activityController.completionWithItemsHandler = {(activityType, completed, returnedItems, activityError) in
// 取消所有选取项目
if let indexPaths = self.collectionView?.indexPathsForSelectedItems {
for indexPath in indexPaths {
self.collectionView?.deselectItem(at: indexPath, animated: false)
}
}
// selectedIcons阵列中移除所有项目
self.selectedIcons.removeAll(keepingCapacity: true)
// 变更分享模式为NO
self.shareEnabled = false
self.collectionView?.allowsMultipleSelection = false
self.shareButton.title = "Share"
self.shareButton.style = UIBarButtonItemStyle.plain
}
present(activityController, animated: true, completion: nil)
}
/*很重要,注意点 因为segue是在每一个cell被按下时会被调用,但当app在分享模式下,我们不要触发这个segue,只要在单选模式时才需要触发它,*/
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "showIconDetail"{
if shareEnabled {return false}
}
return true
}
@IBAction func unwindToHome(segue:UIStoryboardSegue){
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showIconDetail"{
if let indexPaths = collectionView?.indexPathsForSelectedItems{
let destinationController = segue.destination as! IconDetailViewController
destinationController.icon = iconSet[indexPaths[0].row]
collectionView?.deselectItem(at: indexPaths[0], animated: false)
}
}
}
// MARK: UICollectionViewDelegate
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// 检查分享模式是否已经启动,没有的话就离开这个方法
guard shareEnabled else {return}
// 使用indexPath来判断所选的项目并带入一个快照
let selectedIcon = iconSet[indexPath.row]
if let snapshot = collectionView.cellForItem(at: indexPath)?.snapshot {
// 增加选中的item到array
selectedIcons.append((icon: selectedIcon, snapshot: snapshot))
}
}
override func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
// 检查分享模式是否启动,没有的话就离开这个方法
guard shareEnabled else {return}
let deSelectedIcon = iconSet[indexPath.row]
/* 找到所选图示的索引,这里我们使用索引方法并传递一个闭包.在闭包中
我们对所选图示的名称与所选图示阵列的所有项目做比较,
如果名称有符合的话,这个索引方法将会回传其索引值,用这个索引值移除这个item
*/
if let index = selectedIcons.index(where: {$0.icon.name == deSelectedIcon.name}){
selectedIcons.remove(at: index)
}
}
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
// Return the number of sections
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// Return the number of items
return iconSet.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! IconCollectionViewCell
// Configure the cell
let icon = iconSet[indexPath.row]
cell.iconImageView.image = UIImage(named: icon.imageName)
cell.iconPriceLabel.text = "$\(icon.price)"
cell.backgroundView = (icon.isFeatured) ? UIImageView(image: UIImage(named: "feature-bg")) : nil
cell.selectedBackgroundView = UIImageView(image: UIImage(named: "icon-selected"))
return cell
}
}
IconDetailViewController.swift
import UIKit
class IconDetailViewController: UIViewController {
var icon:Icon?
@IBOutlet weak var iconImageView: UIImageView!{
didSet{
iconImageView.image = UIImage(named: icon?.imageName ?? "")
}
}
@IBOutlet weak var nameLabel: UILabel!{
didSet{
nameLabel.text = icon?.name
}
}
@IBOutlet weak var descriptionLabel: UILabel!{
didSet{
descriptionLabel.text = icon?.description
descriptionLabel.numberOfLines = 0
}
}
@IBOutlet weak var priceLabel: UILabel!{
didSet{
if let icon = icon {
priceLabel.text = "$\(icon.price)"
}
}
}
@IBAction func buyAction(_ sender: UIButton) {
}
}
IconCollectionViewCell.swift
class IconCollectionViewCell: UICollectionViewCell {
@IBOutlet var iconImageView: UIImageView!
@IBOutlet var iconPriceLabel: UILabel!
}
Icon.swift
import Foundation
struct Icon {
var name: String = ""
var imageName = ""
var description = ""
var price: Double = 0.0
var isFeatured: Bool = false
init(name: String, imageName: String, description: String, price: Double, isFeatured: Bool) {
self.name = name
self.imageName = imageName
self.description = description
self.price = price
self.isFeatured = isFeatured
}
}
UIView+Snapshot.swift
import Foundation
import UIKit
extension UIView {
/*取得视图快照的方式:以视图的大小来建立一个点阵圆为主的图形内容(context),然后我们渲染(render)视图的Neri,并从中取得图片*/
var snapshot : UIImage? {
var image:UIImage? = nil
UIGraphicsBeginImageContext(bounds.size)
if let context = UIGraphicsGetCurrentContext(){
self.layer.render(in: context)
image = UIGraphicsGetImageFromCurrentImageContext()
}
UIGraphicsEndImageContext()
return image
}
}