[英]How to fix constraints in custom view when collection view cell pressed in swift
我有一個測試應用程序,我第一次嘗試以編程方式創建 100%。 我有一個簡單的 collectionView,每個單元格中有一個圖像和一個標簽。
當我按下單元格時,會彈出一個自定義視圖,其中包含兩個視圖,紅色和藍色,將來會有內容,但現在只有兩個視圖。
我想讓該應用程序在縱向和橫向模式下都能正常工作,而且一開始它運行良好。 我第一次按下單元格時,彈出視圖適用於縱向和橫向。
這就是我想要在按下單元格時發生的情況,但是當我單擊視圖以使其消失時出現問題,然后按下任何單元格:
第一個方向,無論是橫向還是縱向,都很好,但是當我現在改變方向時出現問題,按下第二個或更多單元格。
我嘗試使用首次亮相的視圖層次結構,這就是錯誤屏幕的樣子。
我遵循的主要思想是本網站的教程: https : //iosrevisited.blogspot.com/2017/10/adaptive-autolayout-programmatically-iphone-x.html
我能夠完成本教程,並且效果很好。 我的不同之處在於,我的視圖應該在用戶需要時出現和消失。
這是具有 collectionView 的視圖控制器的代碼:
import UIKit
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100, height: 150)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! TestingCollectionViewCell
cell.backgroundColor = .white
let img = UIImage(named: self.items[indexPath.row])
cell.imageView.image = img
cell.imageName.text = "\(self.items[indexPath.row])"
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("\(items[indexPath.row])")
self.presentInfoView(withInfo: items[indexPath.row])
}
}
class ViewController: UIViewController, BlurDelegate {
func removeBlurView() {
for subview in view.subviews {
if subview.isKind(of: UIVisualEffectView.self) {
subview.removeFromSuperview()
self.infoView.removeFromSuperview()
}
}
}
let infoView: InfoView = {
let view = InfoView()
view.layer.cornerRadius = 5
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
fileprivate var items: [String] = [
"photo1",
"photo2",
"photo3",
"photo4",
"photo5",
"photo6",
"photo7",
"photo8",
"photo9",
"photo10",
"photo11",
"photo12",
"photo13",
"photo14",
"photo15",
"photo16",
"photo17",
"photo18",
"photo19",
"photo20",
"photo21",
"photo22",
"photo23",
"photo24"
]
override func viewDidLoad() {
super.viewDidLoad()
let collection = UICollectionView(frame: view.frame, collectionViewLayout: UICollectionViewFlowLayout())
//allows us to use auto layout constraints
collection.translatesAutoresizingMaskIntoConstraints = false
collection.backgroundColor = .black
view.addSubview(collection)
collection.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
collection.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
collection.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
collection.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
collection.dataSource = self
collection.delegate = self
collection.register(TestingCollectionViewCell.self, forCellWithReuseIdentifier: "cell")
self.navigationItem.title = "Testing"
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
var touch: UITouch? = touches.first
if touch?.view != infoView {
dismissView()
}
}
func dismissView() {
//dismiss(animated: true, completion: nil)
removeBlurView()
}
func setBlurView() {
let blurView = UIVisualEffectView()
blurView.frame = view.frame
blurView.effect = UIBlurEffect(style: .regular)
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurView)
}
func presentInfoView(withInfo info: String) {
setBlurView()
view.addSubview(infoView)
infoView.addView()
let img = UIImage(named: info)
infoView.imageView.image = img
infoView.nameLbl.text = info
infoView.backgroundColor = .white
infoView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
infoView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8).isActive = true
//infoView.widthAnchor.constraint(equalToConstant: view.frame.width - 64).isActive = true
infoView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.8).isActive = true
//infoView.heightAnchor.constraint(equalToConstant: view.frame.height - 64).isActive = true
infoView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -44).isActive = true
infoView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
infoView.alpha = 0
UIView.animate(withDuration: 0.5) {
self.infoView.alpha = 1
self.infoView.transform = .identity
}
}
}
為了稍微清楚一點,我們想要的是讓模糊視圖隨着視圖的出現而出現和消失。
這是單元格出現時將出現的視圖的代碼:
import UIKit
protocol BlurDelegate: class {
func removeBlurView()
}
class InfoView: UIView {
let topView: UIView = {
let view = UIView()
view.backgroundColor = .blue
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let btmView: UIView = {
let view = UIView()
view.backgroundColor = .red
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
var portraitConstraints: [NSLayoutConstraint] = []
var landscapeConstraints: [NSLayoutConstraint] = []
override init(frame: CGRect) {
super.init(frame: frame)
NotificationCenter.default.addObserver(self, selector: #selector(toggleConstraints), name: UIDevice.orientationDidChangeNotification, object: nil)
//addView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder: ) has not been implemented")
}
func addView() {
let guide = self.safeAreaLayoutGuide
//image layout
self.addSubview(topView)
let defaultImgTop = topView.topAnchor.constraint(equalTo: guide.topAnchor)
let defaultImgLeading = topView.leadingAnchor.constraint(equalTo: guide.leadingAnchor)
//portrait
let portraitImgTrailing = topView.trailingAnchor.constraint(equalTo: guide.trailingAnchor)
let portraitImgHeight = topView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.5)
//lbl layouts
self.addSubview(btmView)
let defaultlblTrailing = btmView.trailingAnchor.constraint(equalTo: guide.trailingAnchor)
let defaultLblBottom = btmView.bottomAnchor.constraint(equalTo: guide.bottomAnchor)
//portrait
let portraitLblBottom = btmView.topAnchor.constraint(equalTo: topView.bottomAnchor)
let portraitLblLeading = btmView.leadingAnchor.constraint(equalTo: guide.leadingAnchor)
//imageView landscape constraints
let landscapeImgBottom = topView.bottomAnchor.constraint(equalTo: guide.bottomAnchor)
let landscapeImgWidth = topView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.5)
//label landscape constraints
let landscapeLblTop = btmView.topAnchor.constraint(equalTo: guide.topAnchor)
let landscapeLblLeading = btmView.leadingAnchor.constraint(equalTo: topView.trailingAnchor)
let defaultConstriants = [defaultImgTop, defaultImgLeading, defaultLblBottom, defaultlblTrailing]
portraitConstraints = [portraitImgHeight, portraitImgTrailing, portraitLblBottom, portraitLblLeading]
landscapeConstraints = [landscapeImgBottom, landscapeLblTop, landscapeLblLeading, landscapeImgWidth]
self.addConstraints(defaultConstriants)
toggleConstraints()
}
@objc func toggleConstraints() {
if UIDevice.current.orientation.isLandscape {
self.removeConstraints(portraitConstraints)
self.addConstraints(landscapeConstraints)
} else {
self.removeConstraints(landscapeConstraints)
self.addConstraints(portraitConstraints)
}
}
}
我從上面添加的站點中獲得了這個視圖中的想法。 我不得不改變一些東西,因為它是一個視圖,但它應該是一樣的。 我認為錯誤就在於此,但我嘗試更改縱向和橫向的約束,但沒有奏效。 我試着把它寫下來,看看哪些約束被刪除,然后再次更新,但我似乎無法找到是哪一個讓我感到困惑。 我知道問題應該出在紅色視圖的頂部錨點或藍色視圖的底部錨點,但我無法弄清楚哪個是錯誤的或錯誤的。
我希望這是足夠的信息,但請詢問我是否還有其他需要幫助的地方。
另外,如果不是很麻煩,如果您注意到視圖出現時,導航欄似乎沒有模糊。 這使得自定義視圖看起來像是在頂部被切斷。 如果您知道一種模糊導航欄的方法,或者嘗試將視圖的頂部錨點向下推以使其看起來不那么糟糕,我們將不勝感激。
我試過用
self.navigationItem.bottomAnchor
我試圖在視圖中添加一個帶有常量的頂部錨點,但我上面的配置是我能找到的讓視圖每次都完美顯示的最佳方式。 非常感謝
presentInfoView 函數刪除 infoView.addView()
override init(frame: CGRect) {
super.init(frame: frame)
NotificationCenter.default.addObserver(self, selector: #selector(toggleConstraints), name: UIDevice.orientationDidChangeNotification, object: nil)
addView()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.