Swift:在滚动时更改表格视图高度

Posted

技术标签:

【中文标题】Swift:在滚动时更改表格视图高度【英文标题】:Swift: change tableview height on scroll 【发布时间】:2018-01-04 13:08:06 【问题描述】:

我有一个如图所示的VC

顶部有一个UICollectionView,底部有一个UITableView。 CollectionView 有 1:3 的屏幕,TableView 有 2:3 的屏幕(使用 equalHeight 约束设置)。

我想在 tableView 滚动时更改 UICollectionView 的高度

tableView向上滚动时,我想将 equalHeights 约束的乘数分别更改为 collectionView 和 tableView 的 1:5 和 4:5。这将确保tableView 的高度增加collectionView 减少

tableView向下滚动时,equalHeights 约束的乘数应该重置为默认值

我尝试向 tableView 添加滑动和平移手势,但无法识别。

如何实现这个功能?

P.S:希望通过使用平移手势来实现此功能,以便向上和向下拖动逐渐改变高度。

这是视图层次结构

编辑/更新

这是我正在使用的代码。

class MyConstant 
    var height:CGFloat = 10


let myConstant = MyConstant()

MainScreenVC

override func viewWillAppear(_ animated: Bool) 
    myConstant.height = self.view.frame.size.height


func scrollViewDidScroll(_ scrollView: UIScrollView) 
    if (self.lastContentOffset < scrollView.contentOffset.y) 
        NotificationCenter.default.post(name: Notifications.decreaseHeightNotification.name, object: nil)
        self.topViewConstraint.constant = -self.view.frame.height / 6
        UIView.animate(withDuration: 0.3, animations: 
            self.view.layoutIfNeeded()
        )
     else if (self.lastContentOffset > scrollView.contentOffset.y) 
        NotificationCenter.default.post(name: Notifications.increaseHeightNotification.name, object: nil)
        self.topViewConstraint.constant = 0
        UIView.animate(withDuration: 0.3, animations: 
            self.view.layoutIfNeeded()
        )
    
    self.lastContentOffset = scrollView.contentOffset.y

Cell.Swift

override func awakeFromNib() 
    super.awakeFromNib()

    NotificationCenter.default.addObserver(self, selector: #selector(decreaseHeight), name: Notification.Name("decreaseHeightNotification"), object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(increaseHeight), name: Notification.Name("increaseHeightNotification"), object: nil)

    self.contentView.translatesAutoresizingMaskIntoConstraints = false
    heightConstraint.constant = (myConstant.height / 3) - 10
    widthConstraint.constant = heightConstraint.constant * 1.5


@objc func decreaseHeight() 
    heightConstraint.constant = (myConstant.height / 6) - 10
    widthConstraint.constant = (heightConstraint.constant * 1.5)
    self.layoutIfNeeded()


@objc func increaseHeight() 
    heightConstraint.constant = (myConstant.height / 3) - 10
    widthConstraint.constant = (heightConstraint.constant * 1.5)
    self.layoutIfNeeded()

现在,当我同时滚动两者时,屏幕会冻结。还有没有更好的方法来调整 collectionViewCell 的大小?

【问题讨论】:

你能把你的代码sn-p贴在这里吗?如果没有您使用的方法,这个问题是不完整的。一旦可用,您就可以期待相关的答案。 @nothingwhatsoever 看看 为什么要增加内容视图的高度?它应该是前导,尾随,顶部,底部和单元格,因此它会根据单元格自动增加高度。在表格视图上滚动而不是发布通知后,使用集合视图无效,请参阅此 aplus.rs/2015/… 。您在 Indexpath 中的项目高度做什么。 【参考方案1】:

我还没有测试过,但你可以这样做。在此视图中使用自动布局。它会更好地工作。

将tableview约束设置为Top,Left,Bottom,Right => 0, 0, 0, 0与主视图并将collectionView放在tableview下,约束为Top,Left,Right,height => 0, 0, 0, x 与主视图。

注意:Tableview 位于 collectionView 之上。

连接您的 CollectionView 的高度约束出口并定义您的 defaultOffset 变量

@IBOutlet weak var defaultHeightConstraint: NSLayoutConstraint
var defaultOffSet: CGPoint?

在 viewDidLoad 中,

override func viewDidLoad() 
    super.viewDidLoad()
    tableView.contentInset = UIEdgeInsetsMake(collectionView.size.height, 0, 0, 0)

在viewDidAppear中写

override func viewDidAppear(_ animated: Bool) 
    defaultOffSet = tableView.contentOffset

在 ViewDidScroll 中

func scrollViewDidScroll(_ scrollView: UIScrollView) 
    let offset = tableView.contentOffset

    if let startOffset = self.defaultOffSet 
        if offset.y < startOffset.y 
            // Scrolling down
            // check if your collection view height is less than normal height, do your logic.


            let deltaY = fabs((startOffset.y - offset.y))
            defaultHeightConstraint.constant = defaultHeightConstraint.constant - deltaY

         else 
            // Scrolling up
            let deltaY = fabs((startOffset.y - offset.y))
            defaultHeightConstraint.constant = defaultHeightConstraint.constant + deltaY
        

        self.view.layoutIfNeeded()
    

希望对您有所帮助。

【讨论】:

【参考方案2】:

由于UITableViewUIScrollView 的子类,您的表格视图的delegate 可以接收UIScrollViewDelegate 方法。 你不需要使用 PanGesture

首先实现UITableviewDelegate 并在其中

  var oldContentOffset = CGPoint.zero

  func scrollViewDidScroll(_ scrollView: UIScrollView) 

    let contentOffset =  scrollView.contentOffset.y - oldContentOffset.y

    if (self.oldContentOffset < scrollView.contentOffset.y) 
    // moved to top

     else if (self.oldContentOffset > scrollView.contentOffset.y) 
        // moved to bottom
     else 
        // didn't move
    
        oldContentOffset = scrollView.contentOffset
   

在这里您可以编写逻辑来更改约束的常量值

更新/编辑

另一件事是不要对 tabelview 高度使用乘数。使用集合视图可以很好地使用 self.view 以 1/3 的比例给出高度约束。对于表格视图,只需给出前导、尾随顶部(UICollectionView)和底部。 所以当你改变 UICollectionView 的高度常数时,Tableview 高度会自动降低,反之亦然。

您不能从插座更改乘数,因为它是只读的。所以你必须保持self.view.frame.height / 3的值对你有用

希望对你有帮助

【讨论】:

所以根据你的说法,对于 collectionView:使用 1:3 值的乘数。对于 tableView:添加顶部、底部、左侧和右侧约束。顶部相对于集合视图。滚动时:仅更改乘数值以便自动调整所有内容? @AryanSharma 是的! , 你只需要改变集合视图的高度。由于 tableview top == collectionview.bottom 所以 tableview 会根据集合视图高度的变化自动调整! .而且你不能改变 multiplier value 你必须改变 constat value :)【参考方案3】:

对于更简洁的方法,您为什么不使用UIScrollView 作为容器视图并在其中添加UICollectionViewUITableView,并在禁用tableView 的同时给collectionView 一个高度约束s 滚动直到您的collectionView 的高度限制变为 0。

这是sn-p:

使用 UIScrollViewDelegate 扩展您的 VC 并使用:

func scrollViewDidScroll(_ scrollView: UIScrollView) 

        if scrollView.contentOffset.y >= 0 && scrollView.contentOffset.y <= yourLimit 
            heightConstraint.constant = collectionViewHeight - scrollView.contentOffset.y
            tableView.isScrollEnabled = false

         else if scrollView.contentOffset.y > yourLimit 
            heightConstraint.constant = collectionViewHeight
            tableView.isScrollEnabled = true
        
    

在自定义其中的小东西后试试这个 sn-p。它应该大部分都可以工作,如果没有,我会在这不起作用时分享另一种方法。

【讨论】:

【参考方案4】:

你为什么不直接添加自定义表格单元格和你的集合视图,当 indexPath.row == 0 时,返回你的自定义表格单元格。

【讨论】:

以上是关于Swift:在滚动时更改表格视图高度的主要内容,如果未能解决你的问题,请参考以下文章

在滚动视图中更改 UIView 而 / 更新滚动视图高度 - Swift 3 / Xcode 8

Swift:当节标题高度动态更改时,UITableView 滚动回顶部

滚动表格视图时单元格变为空白(swift)

如何在滚动时更改 UIView 大小并延迟

如何以编程方式设置滚动视图高度

如何在 iOS Swift4 中滚动时增加/减少 UILabel 字体大小以及宽度和高度