繁体   English   中英

AutoLayout 以编程方式划分视图的宽度

[英]AutoLayout divide width of view programatically

我一直在将一些代码从使用框架更改为使用自动布局,但遇到了一个小问题

对于背景,我一直在构建日历,我的问题在于我一直在尝试制作的日历日视图,以便它复制苹果的日历。

这个应用程序自 2018 年以来一直放在我的硬盘中,所以有点过时了,但在 2018 年它做了以下事情:

通过创建EventContainerView并将其放置在TableView上(而不是作为单元格)来显示Events

同时存在的事件会缩短它们的宽度以防止容器视图重叠。

最后一部分是我的问题所在。

我通过获取 tableView 的宽度,将其除以重叠事件的数量,然后将其乘以shiftBy变量来将事件向右移动来做到这一点

在我的一生中,我看不到用 autoLayout 实现这一点的方法。

自动布局之前

func drawEvent(_ event:Event, overlaps:Int, shiftBy:Int) -> EventContainerView{
....
....


let eventWidth = (tableView.frame.width - 30) / CGFloat(overlaps)
        
        let shift = eventWidth * CGFloat(shiftBy)
        var frame: CGRect
     if(shiftBy > 0){
         frame = CGRect(x: CGFloat(30 + (5*shiftBy)) + shift, y: startPoint, width: eventWidth, height: endpoint)
         
     }else{
         frame = CGRect(x: CGFloat(30) + shift, y: startPoint, width: eventWidth, height: endpoint)
         
     }

自动布局之后

func drawEvent(_ event:Event, overlaps:Int, shiftBy:Int) -> EventContainerView{
....
....

let eventView = EventContainerView(forEvent: event, today: self)
           eventView.translatesAutoresizingMaskIntoConstraints = false
 var left: NSLayoutConstraint = eventView.leftAnchor.constraint(equalTo: tableView.leftAnchor, constant: +20)
   
    if(shiftBy>0){
        left = ????
    }
    
    tableView.addSubview(eventView)
        let layout = [eventView.topAnchor.constraint(equalTo: tableView.topAnchor, constant: startPoint),
        left,
        eventView.heightAnchor.constraint(equalToConstant: endpoint),
        eventView.widthAnchor.constraint(equalTo: tableView.widthAnchor, multiplier: 1/CGFloat(overlaps), constant: -30)]
    NSLayoutConstraint.activate(layout)
        return eventView

任何人都可以就我如何实现这段代码提供任何建议吗?

谢谢

编辑

这就是我想要实现的(我在 macOS 的日历上使用了这个,但它仍然清楚地显示了我希望日历事件如何出现)

重叠事件彼此相邻堆叠

这就是我所拥有的(15 到 16 之间的深黄色是堆叠在“测试一切”事件下方的另一个事件。我需要其中一个切换(以及可能添加或可能不添加到同一事件的任何其他事件)大体时间)

应用程序的事件堆叠在彼此之上,而不是相邻

许多不同的方法来解决这个问题,但要让它接近你正在做的事情......

您可以通过以下方式创建跨越宽度的等宽视图,使用它们之间的固定间距和每侧的特定“填充”:

  • 将第一个视图的Leading约束到superview的Leading + padding
  • 将每个连续视图的前导约束到上一个视图的尾随 + 间距
  • 将 Last 视图的 Trailing 约束到 superview 的 Trailing - padding

然后,约束每个视图的宽度等于前一个视图的宽度。

这是一个简单的例子:

class AndyViewController: UIViewController {

    let numEvents = 1
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // a var to track the previously added view
        var prevView: UIView!
        
        var startPoint: CGFloat = 100
        
        // create a couple eventViews
        for i in 0..<numEvents {
            let thisView = eventView()
            view.addSubview(thisView)
            
            // set top constraint
            thisView.topAnchor.constraint(equalTo: view.topAnchor, constant: startPoint).isActive = true
            
            // let's pretend each view is 20-pts "later"
            startPoint += 20.0
            
            // for now, make them all 50-pts tall
            thisView.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
            
            // if it's the first view
            if i == 0 {
                // constrain its leading to view leading + 30
                thisView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30.0).isActive = true
            } else {
                // make sure prevView has been set
                guard let pv = prevView else {
                    fatalError("Did something wrong!!!")
                }
                // start this view at the right-end of the previous view + 5
                thisView.leadingAnchor.constraint(equalTo: prevView.trailingAnchor, constant: 5.0).isActive = true
                // make this view width equal to previous view width
                thisView.widthAnchor.constraint(equalTo: pv.widthAnchor).isActive = true
            }
            
            // if it's the last view
            if i == numEvents - 1 {
                // constrain its trailing to view trailing -30
                thisView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30).isActive = true
            }
            
            // set prevView to thisView
            prevView = thisView
        }
        
    }

    func eventView() -> UIView {
        let v = UIView()
        v.backgroundColor = UIColor.yellow.withAlphaComponent(0.8)
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }
    
}

结果,使用 1、2、3 或 4 个“事件”:

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

您应该能够根据自己的需要进行调整。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM