#30 利用 Compositional Layout 製作特殊版型照片牆(Flickr API)

UICollectionViewCompositionalLayout / Flickr API / Preview Tool

--

Demo

加入 collectionView / 抓資料放屬性 photos

用到 UICollectionViewinit(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) 生成 collectionView。

createLayout 函式後面談。

SearchData 結構體

遵從 UICollectionViewDataSource

設定 … numberOfItemsInSection …,設定 … cellForItemAt …,把資料內的 imageUrl 傳給 cell 的 imageURL,再拿 cell 的 imageURL 下載圖片,最後把 image 物件放進 cell.imageView.image 顯示。

MyCollectionViewCell

import UIKitclass MyCollectionViewCell: UICollectionViewCell {
static let identifier = "MyCollectionViewCell"

var imageURL: URL!

let imageView: UIImageView = {
let imageView = UIImageView()
imageView.clipsToBounds = true
imageView.contentMode = .scaleAspectFill
return imageView
}()

override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(imageView)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func layoutSubviews() {
super.layoutSubviews()
imageView.frame = contentView.bounds
}

}

先前呼叫的 createLayout() 最終回傳 UICollectionViewCompositionalLayoutinit(section: NSCollectionLayoutSection) 生成的 UICollectionViewLayout 型別物件

Compositional Layout 結構/padding = 10/padding = 2

重點說明:以右上角 doubletVerticalGroup 和 doubletItem 為例。

let doubletItem = NSCollectionLayoutItem(
// NSCollectionLayoutSize 決定該物件與「所屬容器」的比例關係
layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1),
heightDimension: .fractionalHeight(1) //所屬group已經有count:2,故填什麼都沒差
)
)
let doubletVerticalGroup = NSCollectionLayoutGroup.vertical(
layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1/3),
heightDimension: .fractionalHeight(1)
),
subitem: doubletItem, count: 2 //該group的subitem是誰及其數量
)
//設定contentInsets,往物件內「裁切邊距」doubletVerticalGroup.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: padding/2, bottom: 0, trailing: padding/2)//設定interItemSpacing,在item間「推出邊距」(不會裁切)
doubletVerticalGroup.interItemSpacing = NSCollectionLayoutSpacing.fixed(padding)

即時預覽功能 Snippets:

#if canImport(SwiftUI) && DEBUG
import SwiftUI
@available(iOS 13.0, *)
struct UIViewControllerPreview<ViewController: UIViewController>: UIViewControllerRepresentable {
let viewController: ViewController
init(_ builder: @escaping () -> ViewController) {
viewController = builder()
}
func makeUIViewController(context: Context) -> some UIViewController {
viewController
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: UIViewControllerRepresentableContext<UIViewControllerPreview<ViewController>>) {
return
}
}
#endif
#if canImport(SwiftUI) && DEBUG
import SwiftUI
// 可加入多個裝置
let deviceNames: [String] = [
"iPhone 13 Pro Max"
]
@available(iOS 13.0, *)
struct ViewController_Previews: PreviewProvider {
static var previews: some View {
ForEach(deviceNames, id: \.self) { deviceName in
UIViewControllerPreview {
ViewController()
}
.previewDevice(PreviewDevice(rawValue: deviceName))
.previewDisplayName(deviceName)
}.previewInterfaceOrientation(.portrait)
}
}
#endif

--

--

Ethan
Ethan

Written by Ethan

Life is what happens to you while you’re busy making other plans.

No responses yet