location97 2015-08-03 07:25 采纳率: 0%
浏览 3081

使用masonry的具体适配遇到的问题。(有关scrollview的)

在使用masonry进行适配的时候,在控件下面垫了一层scrollview,在用约束条件的时候,以scrollview为父控件,或者以weakself(self.view)为父控件都不能进行滑动。为什么?

  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-08-04 03:32
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    这个问题是由于iOS中的一种特性——滚动视图与子视图之间的关系所导致的。

    Masonry是一种网格布局技术,它允许开发者将多个视图放在一个容器中,并且通过自定义属性来控制它们的位置和大小。然而,如果你试图在一个滚动视图(ScrollView)下放置一个子视图(比如一个Masonry视图),你可能会遇到以下问题:

    1. 视图无法正确缩放:如果滚动视图中的子视图过大或过小,那么它的实际尺寸可能不会完全匹配其在屏幕上的位置。这会导致视图看起来不自然或变形。

    2. 视图之间没有足够的空间:当一个子视图被放置在滚动视图下时,它可能会与其他视图竞争可用的空间。例如,如果滚动视图的最小高度设置得足够低,那么子视图可能会因为缺乏空间而被压缩到不可见的状态。

    3. 触发滚动事件:当你尝试在滚动视图下的子视图上添加手势事件监听器时,这些事件会触发滚动视图本身而不是子视图。这是因为滚动视图通常包含了一些额外的功能,如分页、页面切换等,这些功能并不总是适用于所有的情况。

    解决这个问题的方法是确保滚动视图的最小高度足够高,以便所有的子视图都能在其可见范围内。此外,你可以考虑使用一些其他的技术来管理子视图的行为,比如使用一个新的层次结构来组织你的UI,或者使用第三方库如AFNetworking来处理网络请求。

    这是一个简单的例子,展示如何创建一个滚动视图并将其内容分割成多行:

    import UIKit
    
    class ViewController: UIViewController, UIScrollViewDelegate {
        
        @IBOutlet weak var scrollView: UIScrollView!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
            let lines = content.split(separator: "\n")
            
            for line in lines {
                let label = UILabel()
                label.text = line
                label.numberOfLines = 0
                
                let subView = UIView(frame: CGRect(x: 0, y: CGFloat(scrollView.contentOffset.y), width: scrollView.frame.width, height: 40))
                
                // Add a scroll view to the bottom of the sub view to simulate scrolling
                let scroller = ScrollView()
                scroller.backgroundColor = .clear
                scroller.delegate = self
                scroller.contentSize = CGSize(width: 50, height: 50)
                scroller.scrollEnabled = false
                
                subView.addSubview(scroller)
                
                label.translatesAutoresizingMaskIntoConstraints = false
                subView.translatesAutoresizingMaskIntoConstraints = false
                
                NSLayoutConstraint.activate([
                    label.centerXAnchor.constraint(equalTo: subView.centerXAnchor),
                    label.topAnchor.constraint(equalTo: subView.topAnchor),
                    label.bottomAnchor.constraint(equalTo: subView.bottomAnchor),
                    
                    subView.leadingAnchor.constraint(equalTo: subView.leadingAnchor, constant: 8),
                    subView.trailingAnchor.constraint(equalTo: subView.trailingAnchor, constant: -8),
                    
                    label.heightAnchor.constraint(equalToConstant: 20),
                    label.widthAnchor.constraint(equalToConstant: 20),
                    
                    subView.widthAnchor.constraint(equalToConstant: 50),
                    subView.heightAnchor.constraint(equalToConstant: 50),
                ])
                
                scrollView.addSubview(subView)
            }
        }
        
        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            if scrollView.contentOffset.y > 0 {
                // Simulate scrolling by adding a new line
                let line = "New line added at the bottom"
                let newLineLabel = UILabel()
                newLineLabel.text = line
                newLineLabel.numberOfLines = 0
                newLineLabel.font = UIFont.systemFont(ofSize: 16, weight: .semibold)
                newLineLabel.textAlignment = .center
                
                let newSubView = UIView(frame: CGRect(x: 0, y: CGFloat(scrollView.contentOffset.y), width: scrollView.frame.width, height: 40))
                newSubView.backgroundColor = .clear
                newSubView.addSubview(newLineLabel)
                
                let newScroller = ScrollView()
                newScroller.backgroundColor = .clear
                newScroller.delegate = self
                newScroller.contentSize = CGSize(width: 50, height: 50)
                newScroller.scrollEnabled = false
                
                newSubView.addSubview(newScroller)
                
                newLineLabel.translatesAutoresizingMaskIntoConstraints = false
                newSubView.translatesAutoresizingMaskIntoConstraints = false
                
                NSLayoutConstraint.activate([
                    newLineLabel.centerXAnchor.constraint(equalTo: newSubView.centerXAnchor),
                    newLineLabel.topAnchor.constraint(equalTo: newSubView.topAnchor),
                    newLineLabel.bottomAnchor.constraint(equalTo: newSubView.bottomAnchor),
                    
                    newSubView.leadingAnchor.constraint(equalTo: newSubView.leadingAnchor, constant: 8),
                    newSubView.trailingAnchor.constraint(equalTo: newSubView.trailingAnchor, constant: -8),
                    
                    newLineLabel.heightAnchor.constraint(equalToConstant: 20),
                    newLineLabel.widthAnchor.constraint(equalToConstant: 20),
                    
                    newSubView.widthAnchor.constraint(equalToConstant: 50),
                    newSubView.heightAnchor.constraint(equalToConstant: 50),
                ])
                
                scrollView.addSubview(newSubView)
            }
        }
    }
    

    在这个例子中,我们创建了一个新的滚动视图,然后添加了新行到这个视图。注意,这里我们模拟了一个滚动行为,实际上应该使用真正的滚动视图和其他视图交互。

    评论

报告相同问题?