我添加了一个GIF,以更好地显示我要实现的目标:
我该如何实现?
一些想法:
可能制作一个containerView的集合视图?
还是可以使用视图? (这似乎最简单,但是我需要能够在完整的Content视图中包含一个containerView)
注意:我只需要在一个地方创建这种功能,因此,如果我要使用collectionView,它将始终只有1个Cell。
另外,我想实现的另一个例子,也许是一个更好的例子是apple photos应用。在其中,您可以看到图像的集合视图,当您点击其中一个图像时,它会展开为全屏,但会显示为VC。我还希望获得在照片应用中向下滑动时获得的自由感觉。
答案 0 :(得分:2)
如果要使用集合视图的单元格来做。
//
// ViewController.swift
// test
//
// Created by Sergio Rodríguez Rama on 22/04/2019.
// Copyright © 2019 Sergio Rodríguez Rama. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
private var smallView: UIView?
private var smallFrame: CGRect?
private var bigFrame: CGRect?
@objc private func viewTapped() {
UIView.animate(withDuration: 1, animations: { [weak self] in
guard let smallFrame = self?.smallFrame else { return }
self?.smallView?.frame = smallFrame
}) { [weak self] _ in
self?.smallView?.removeFromSuperview()
self?.collectionView.isUserInteractionEnabled = true
}
}
override func viewDidLoad() {
super.viewDidLoad()
bigFrame = view.frame
collectionView.delegate = self
collectionView.dataSource = self
}
}
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath)
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) else { return }
smallFrame = collectionView.convert(cell.frame, to: view)
smallView = cell.copyView()
guard let smallFrame = smallFrame, let smallView = smallView else { return }
smallView.frame = smallFrame
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(viewTapped))
smallView.addGestureRecognizer(tapGestureRecognizer)
view.addSubview(smallView)
collectionView.isUserInteractionEnabled = false
UIView.animate(withDuration: 1, animations: { [weak self] in
guard let frame = self?.bigFrame else { return }
self?.smallView?.frame = frame
})
}
}
extension UIView
{
func copyView<T: UIView>() -> T {
return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self)) as! T
}
}
答案 1 :(得分:1)
您可以在视图内部查看要修改的框架。您必须使用约束。
例如,您可以将标签限制在红色视图的顶部和顶部:
这是视图控制器的代码:
//
// ViewController.swift
// test
//
// Created by Sergio Rodríguez Rama on 22/04/2019.
// Copyright © 2019 Sergio Rodríguez Rama. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
private enum SmallViewStatus {
case small
case big
}
private var smallViewStatus: SmallViewStatus = .small
private func toggleStatus() {
if smallViewStatus == .small {
smallViewStatus = .big
} else if smallViewStatus == .big {
smallViewStatus = .small
}
}
private let smallFrame: CGRect = CGRect(x: 100, y: 100, width: 100, height: 100)
private lazy var smallView: UIView = {
let view = UIView(frame: smallFrame)
view.backgroundColor = .red
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(smallViewTapped))
view.addGestureRecognizer(tapGestureRecognizer)
return view
}()
private lazy var label: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "HELLO"
return label
}()
@objc private func smallViewTapped() {
UIView.animate(withDuration: 1, animations: { [weak self] in
guard let newFrame = self?.smallViewStatus == .small ? self?.view.frame : self?.smallFrame else { return }
self?.smallView.frame = newFrame
}) { [weak self] _ in
self?.toggleStatus()
}
}
override func viewDidLoad() {
super.viewDidLoad()
smallView.addSubview(label)
label.topAnchor.constraint(equalTo: smallView.topAnchor, constant: 50).isActive = true
label.leadingAnchor.constraint(equalTo: smallView.leadingAnchor).isActive = true
view.addSubview(smallView)
}
}
答案 2 :(得分:0)
提供的两个答案都是糟糕的架构示例,不允许在视图尺寸之外进行自定义。
您需要向您的视图/单元添加一个操作,该操作将打开另一个视图控制器。
在该视图控制器中,您将传递要渲染的数据,然后在该视图控制器中将其全屏显示。从那里,您可以将其他子视图添加到控制器。