gpt4 book ai didi

ios - CollectionView 在 StackView 中消失(Swift)

转载 作者:搜寻专家 更新时间:2023-11-01 05:49:51 26 4
gpt4 key购买 nike

我正在尝试实现此图中间所示的 stackView 排列:the middle of this figure , 但由于某种原因,包含 collectionView 的顶部堆栈在使用时消失了:.fill 分布

stackView.distribution = .fill        (stack containing collectionView disappears)
stackView.distribution = .fillEqually (collectionView appears fine in stackView)

我已经为此苦苦挣扎了好几天,您会在我注释掉的部分中看到残留物:设置 compressionResistance/hugging 优先级、尝试更改固有高度、更改 UICollectionViewFlowLayout() 的 .layout.itemSize 等。 .. 在我手中没有任何作用。如果您只需将其粘贴并与空的 UIViewController 相关联,此处的代码就会运行。顶部的 collectionView 堆栈包含一个 pickerView,下面的堆栈是一个 pageControllView、按钮子堆栈和一个 UIView。在 .fillEqually 分布中一切正常,所以这纯粹是一个布局问题。非常感谢!

// CodeStackVC2
// Test of programmatically generated stack views
// Output: nested stack views
// To make it run:
// 1) Assign the blank storyboard VC as CodeStackVC2
// 2) Move the "Is Inital VC" arrow to the blank storyboard

import UIKit

class CodeStackVC2: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate,UICollectionViewDelegateFlowLayout, UIGestureRecognizerDelegate {

let fruit = ["Apple", "Orange", "Plum", "Qiwi", "Banana"]
let veg = ["Lettuce", "Carrot", "Celery", "Onion", "Brocolli"]
let meat = ["Beef", "Chicken", "Ham", "Lamb"]
let bread = ["Wheat", "Muffin", "Rye", "Pita"]
var foods = [[String]]()
let button = ["bread","fruit","meat","veg"]

var sView = UIStackView()
let cellId = "cellId"

override func viewDidLoad() {
super.viewDidLoad()
foods = [fruit, veg, meat, bread]
setupViews()
}

//MARK: Views
lazy var cView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
layout.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
layout.itemSize = CGSize(width: self.view.frame.width, height: 120)
let cv = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
cv.backgroundColor = UIColor.lightGray
cv.isPagingEnabled = true
cv.dataSource = self
cv.delegate = self
cv.isUserInteractionEnabled = true
// var intrinsicContentSize: CGSize {
// return CGSize(width: UIViewNoIntrinsicMetric, height: 120)
// }
return cv
}()

lazy var pageControl: UIPageControl = {
let pageC = UIPageControl()
pageC.numberOfPages = self.foods.count
pageC.pageIndicatorTintColor = UIColor.darkGray
pageC.currentPageIndicatorTintColor = UIColor.white
pageC.backgroundColor = .lightGray
pageC.addTarget(self, action: #selector(changePage(sender:)), for: UIControlEvents.valueChanged)
// pageC.setContentHuggingPriority(900, for: .vertical)
// pageC.setContentCompressionResistancePriority(100, for: .vertical)
return pageC
}()

var readerView: UIView = {
let rView = UIView()
rView.backgroundColor = UIColor.brown
// rView.setContentHuggingPriority(100, for: .vertical)
// rView.setContentCompressionResistancePriority(900, for: .vertical)
return rView
}()


func makeButton(_ name:String) -> UIButton{
let newButton = UIButton(type: .system)
let img = UIImage(named: name)?.withRenderingMode(.alwaysTemplate)
newButton.setImage(img, for: .normal)
newButton.contentMode = .scaleAspectFit
newButton.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleButton)))
newButton.isUserInteractionEnabled = true
newButton.backgroundColor = .orange
return newButton
}
//Make a 4-item vertical stackView containing
//cView,pageView,subStackof 4-item horiz buttons, readerView
func setupViews(){
cView.register(FoodCell.self, forCellWithReuseIdentifier: cellId)
//generate an array of buttons
var buttons = [UIButton]()
for i in 0...foods.count-1 {
buttons += [makeButton(button[i])]
}
let subStackView = UIStackView(arrangedSubviews: buttons)
subStackView.axis = .horizontal
subStackView.distribution = .fillEqually
subStackView.alignment = .center
subStackView.spacing = 20
//set up the stackView
let stackView = UIStackView(arrangedSubviews: [cView,pageControl,subStackView,readerView])
stackView.axis = .vertical
//.fillEqually works, .fill deletes cView, .fillProportionally & .equalSpacing delete cView & readerView
stackView.distribution = .fillEqually
stackView.alignment = .fill
stackView.spacing = 5
//Add the stackView using AutoLayout
view.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 5).isActive = true
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}

func handleButton() {
print("button pressed")
}
//pageControl page changer
func changePage(sender: AnyObject) -> () {
let x = CGFloat(pageControl.currentPage) * cView.frame.size.width
cView.setContentOffset(CGPoint(x:x, y:0), animated: true)
}

//MARK: horizontally scrolling Chapter collectionView
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// let scrollBarLeft = CGFloat(scrollView.contentOffset.x) / CGFloat(book.chap.count + 1)
// let scrollBarWidth = CGFloat( menuBar.frame.width) / CGFloat(book.chap.count + 1)
}

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let index = targetContentOffset.pointee.x / view.frame.width
pageControl.currentPage = Int(index) //change PageControl indicator
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return foods.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! FoodCell
cell.foodType = foods[indexPath.item]
return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 120)
}
}

class FoodCell:UICollectionViewCell, UIPickerViewDelegate, UIPickerViewDataSource {

var foodType: [String]? {
didSet {
pickerView.reloadComponent(0)
pickerView.selectRow(0, inComponent: 0, animated: true)
}
}

lazy var pickerView: UIPickerView = {
let pView = UIPickerView()
pView.frame = CGRect(x:0,y:0,width:Int(pView.bounds.width), height:Int(pView.bounds.height))
pView.delegate = self
pView.dataSource = self
pView.backgroundColor = .darkGray
return pView
}()

override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}

func setupViews() {
backgroundColor = .clear
addSubview(pickerView)
addConstraintsWithFormat("H:|[v0]|", views: pickerView)
addConstraintsWithFormat("V:|[v0]|", views: pickerView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if let count = foodType?.count {
return count
} else {
return 0
}
}

func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let pickerLabel = UILabel()
pickerLabel.font = UIFont.systemFont(ofSize: 15)
pickerLabel.textAlignment = .center
pickerLabel.adjustsFontSizeToFitWidth = true
if let foodItem = foodType?[row] {
pickerLabel.text = foodItem
pickerLabel.textColor = .white
return pickerLabel
} else {
print("chap = nil in viewForRow")
return UIView()
}
}


}

最佳答案

问题是您有一个固定高度的堆栈 View ,其中包含两个没有固有内容大小的 View (cView 和 readerView)。您需要告诉布局引擎应该如何调整这些 View 的大小以填充堆栈 View 中的剩余空间。

当您使用 .fillEqually 分布时它会起作用,因为您告诉布局引擎使堆栈 View 中的所有四个 View 具有相同的高度。这定义了 cView 和 readerView 的高度。

当您使用 .fill 分布时,无法确定 cView 和 readerView 应该有多高。在您添加更多约束之前,布局是不明确的。内容优先级没有任何作用,因为这些 View 没有可以拉伸(stretch)或压缩的固有大小。您需要设置其中一个没有固有尺寸的 View 的高度,另一个将占用剩余空间。

问题是collection view应该多高?您希望它与阅读器 View 大小相同还是容器 View 的某个比例?

例如,假设您的设计要求 Collection View 占容器 View 高度的 25%,而 readerView 使用剩余空间(其他两个 View 处于其自然固有内容大小)。您可以添加以下约束:

NSLayoutConstraint.activate([
cView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.25)
])

一个更简单的例子

将布局缩减为最基本的元素。您有一个固定到其父 View 的堆栈 View ,其中有四个排列的 subview ,其中两个没有固有内容大小。例如,这是一个带有两个普通 UIView、一个标签和一个按钮的 View Controller :

class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}

private func setupViews() {

let blueView = UIView()
blueView.backgroundColor = .blue

let titleLabel = UILabel()
titleLabel.text = "Hello"

let button = UIButton(type: .system)
button.setTitle("Action", for: .normal)

let redView = UIView()
redView.backgroundColor = .red

let stackView = UIStackView(arrangedSubviews: [blueView, titleLabel, button, redView])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 8
view.addSubview(stackView)

NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
stackView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor),
stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
blueView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.25)
])
}
}

这是它在 iPhone 上的外观,蓝色 View 使用 25% 的垂直空间:

iPhone Screenshot

关于ios - CollectionView 在 StackView 中消失(Swift),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45249732/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com