Ios 我需要未知元素的顶部约束

Ios 我需要未知元素的顶部约束,ios,swift,constraints,nslayoutconstraint,Ios,Swift,Constraints,Nslayoutconstraint,我有一个通过点击按钮从服务器下载图像的应用程序。下载图像后,我创建一个新的imageView并将其添加到MyContentView(UIView)中。我需要创建约束-每个新的imageview都需要上一个的顶部约束 func addNewImageToTheScrollView(img: UIImage?) { if let imageResponse = img { let imageView = UIImageView(image: imageResponse.cro

我有一个通过点击按钮从服务器下载图像的应用程序。下载图像后,我创建一个新的imageView并将其添加到MyContentView(UIView)中。我需要创建约束-每个新的imageview都需要上一个的顶部约束

func addNewImageToTheScrollView(img: UIImage?) {
    if let imageResponse = img {
        let imageView = UIImageView(image: imageResponse.crop(rect: CGRect(x: 0, y: imageResponse.size.height/2, width: self.contentView.frame.width, height: 200)))
        self.contentView.addSubview(imageView)

        imageView.translatesAutoresizingMaskIntoConstraints = false
        let x = NSLayoutConstraint(item: imageView, attribute: .centerX, relatedBy: .equal, toItem: self.contentView, attribute: .centerX, multiplier: 1.0, constant: 0)
        let y = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 30)
        let width = NSLayoutConstraint(item: imageView, attribute: .width, relatedBy: .equal, toItem: self.contentView, attribute: .width, multiplier: 1.0, constant: 0)
        let height = NSLayoutConstraint(item: imageView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 150)

        self.contentView.addConstraints([x, y])
        imageView.addConstraints([width, height])
    }
}
如果我对约束代码进行注释,它将正常工作,除非每个新的imageView都位于视图顶部的同一位置。现在有了这个约束代码,我下载后就有了这样的代码问题

2017-07-02 14:50:01.018 ImageFromServerTest[11516:1080948]***由于未捕获的异常“NSInvalidArgumentException”终止应用程序,原因:“NSLayoutConstraint for>:0的乘数或零秒项以及第一个属性的位置会创建等于常量的位置非法约束。位置属性必须成对指定。'


我相信你在这里遇到了一个问题:

let y = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 30)
“toItem”参数应该有一些值。此外,第一个参数应该是imageView.topAnchor。可能应该是这样的:

let y = NSLayoutConstraint(item: imageView.topAnchor, attribute: .top, relatedBy: .equal, toItem: self.contentView.topAnchor, attribute: .notAnAttribute, multiplier: 1.0, constant: 30)

我相信你在这里遇到了一个问题:

let y = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 30)
“toItem”参数应该有一些值。此外,第一个参数应该是imageView.topAnchor。可能应该是这样的:

let y = NSLayoutConstraint(item: imageView.topAnchor, attribute: .top, relatedBy: .equal, toItem: self.contentView.topAnchor, attribute: .notAnAttribute, multiplier: 1.0, constant: 30)

无论何时使用ScrollView,都有两条经验法则:-

  • 给出与superview相关的scrollView前导、尾随、底部和顶部约束,即
    self.view

     @IbOutlet weak var scrollView: UIScrollView!
    
        let leading = NSLayoutConstraint(item: scrollView, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leadingMargin, multiplier: 1.0, constant: 0)
    
        let trailing = NSLayoutConstraint(item: scrollView, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailingMargin, multiplier: 1.0, constant: 0)
    
        let top = NSLayoutConstraint(item: scrollView, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1.0, constant: 0)
    
        let bottom = NSLayoutConstraint(item: scrollView, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1.0, constant: 0)
    
  • 向contentView添加与scrollView相关的约束

    @IbOutlet weak var contentView: UIView!
    
     let leading = NSLayoutConstraint(item: contentView, attribute: .leading, relatedBy: .equal, toItem: scrollView, attribute: .leading, multiplier: 1.0, constant: 0)
     let trailing = NSLayoutConstraint(item: contentView, attribute: .trailing, relatedBy: .equal, toItem: scrollView, attribute: .trailing, multiplier: 1.0, constant: 0)
    
     let top = NSLayoutConstraint(item: contentView, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .top, multiplier: 1.0, constant: 0)
    
      //increase the constant according to how much long you need the scrollview to be
     let bottom = NSLayoutConstraint(item: contentView, attribute: .bottom, relatedBy: .equal, toItem: scrollView, attribute: .bottom, multiplier: 1.0, constant: 0) 
    
  • 现在,添加与contentView相关的子视图约束(标签、图像)

    例如,您收到了第一个图像,因此我们将在函数外部维护UIImageView数组

    var imageViews = [UIImageViews]() //declared outside the function
    
    
        //received an image here
            var imageView = UIImageView() // define the frame according to yourself using frame init method
            imageView.image = image
    
        if imageViews.isEmpty { // first image view 
        //add constraints to first image view
    
        let x = NSLayoutConstraint(item: imageView, attribute: .centerX, relatedBy: .equal, toItem: contentView, attribute: .centerX, multiplier: 1.0, constant: 0)
        let y = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .top, multiplier: 1.0, constant: 30)
        let width = NSLayoutConstraint(item: imageView, attribute: .width, relatedBy: .equal, toItem: self.contentView, attribute: .width, multiplier: 1.0, constant: 0)
        let height = NSLayoutConstraint(item: imageView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 150)
        }
    
    else { //second, third, fourth image view... so on
    
        let x = NSLayoutConstraint(item: imageView, attribute: .centerX, relatedBy: .equal, toItem: contentView, attribute: .centerX, multiplier: 1.0, constant: 0)
        let y = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: imageViews[imageViews.count - 1], attribute: .bottom, multiplier: 1.0, constant: 30)
    
        let width = NSLayoutConstraint(item: imageView, attribute: .width, relatedBy: .equal, toItem: self.contentView, attribute: .width, multiplier: 1.0, constant: 0)
        let height = NSLayoutConstraint(item: imageView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 150)
    }
    
          imageViews.append(imageView) 
    }
    
    希望你现在有一个想法,如何处理这个问题。如果有4个或5个以上的ImageView,您可能需要检查数组的计数,并相应地增加scrollView的contentView。您可以使用
    self.scrollView.contentSize=CGSize(宽度、高度)

    无论何时使用scrollView,都有两条经验法则:-

  • 给出与superview相关的scrollView前导、尾随、底部和顶部约束,即
    self.view

     @IbOutlet weak var scrollView: UIScrollView!
    
        let leading = NSLayoutConstraint(item: scrollView, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leadingMargin, multiplier: 1.0, constant: 0)
    
        let trailing = NSLayoutConstraint(item: scrollView, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailingMargin, multiplier: 1.0, constant: 0)
    
        let top = NSLayoutConstraint(item: scrollView, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1.0, constant: 0)
    
        let bottom = NSLayoutConstraint(item: scrollView, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1.0, constant: 0)
    
  • 向contentView添加与scrollView相关的约束

    @IbOutlet weak var contentView: UIView!
    
     let leading = NSLayoutConstraint(item: contentView, attribute: .leading, relatedBy: .equal, toItem: scrollView, attribute: .leading, multiplier: 1.0, constant: 0)
     let trailing = NSLayoutConstraint(item: contentView, attribute: .trailing, relatedBy: .equal, toItem: scrollView, attribute: .trailing, multiplier: 1.0, constant: 0)
    
     let top = NSLayoutConstraint(item: contentView, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .top, multiplier: 1.0, constant: 0)
    
      //increase the constant according to how much long you need the scrollview to be
     let bottom = NSLayoutConstraint(item: contentView, attribute: .bottom, relatedBy: .equal, toItem: scrollView, attribute: .bottom, multiplier: 1.0, constant: 0) 
    
  • 现在,添加与contentView相关的子视图约束(标签、图像)

    例如,您收到了第一个图像,因此我们将在函数外部维护UIImageView数组

    var imageViews = [UIImageViews]() //declared outside the function
    
    
        //received an image here
            var imageView = UIImageView() // define the frame according to yourself using frame init method
            imageView.image = image
    
        if imageViews.isEmpty { // first image view 
        //add constraints to first image view
    
        let x = NSLayoutConstraint(item: imageView, attribute: .centerX, relatedBy: .equal, toItem: contentView, attribute: .centerX, multiplier: 1.0, constant: 0)
        let y = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .top, multiplier: 1.0, constant: 30)
        let width = NSLayoutConstraint(item: imageView, attribute: .width, relatedBy: .equal, toItem: self.contentView, attribute: .width, multiplier: 1.0, constant: 0)
        let height = NSLayoutConstraint(item: imageView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 150)
        }
    
    else { //second, third, fourth image view... so on
    
        let x = NSLayoutConstraint(item: imageView, attribute: .centerX, relatedBy: .equal, toItem: contentView, attribute: .centerX, multiplier: 1.0, constant: 0)
        let y = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: imageViews[imageViews.count - 1], attribute: .bottom, multiplier: 1.0, constant: 30)
    
        let width = NSLayoutConstraint(item: imageView, attribute: .width, relatedBy: .equal, toItem: self.contentView, attribute: .width, multiplier: 1.0, constant: 0)
        let height = NSLayoutConstraint(item: imageView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 150)
    }
    
          imageViews.append(imageView) 
    }
    
    希望你现在有一个想法,如何处理这个问题。如果有4个或5个以上的ImageView,您可能需要检查数组的计数,并相应地增加scrollView的contentView。您可以使用
    self.scrollView.contentSize=CGSize(宽度、高度)

    没有帮助(2017-07-02 15:42:51.208 ImageFromServerTest[12886:1114489]***由于未捕获的异常“NSInvalidArgumentException”终止应用程序,原因:“NSLayoutConstraint for:Unknown layout attribute”它没有帮助(2017-07-02 15:42:51.208 ImageFromServerTest[12886:1114489]***由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“NSLayoutConstraint for:Unknown layout attribute”已投票通过。我准备发表一篇评论,对此进行说明,但我认为这更像是一个答案。但后来我意识到,除了我的“答案”,还有更多的内容(来自OP中暗示的其他内容)提供-所以我没有发布任何东西。很好地解释了在UIScrollView中正确设置的各种内容。你太棒了,谢谢。)我想我需要花很多时间来理解if-else约束(我自己)是的,理解事情需要时间…顺便说一句,我建议你跟随这个频道,提高你的技能…投票结果。我准备发表一篇评论,说一些这方面的话,但我认为这更像是一个答案。但后来我意识到还有更多(来自OP中暗示的其他内容)而不是我提供的“答案”——因此我没有发布任何内容。在UIScrollView中解释正确设置的各种内容做得很好。你太棒了,谢谢)“我认为这将是一个很长的时间让我了解如果其他约束我自己)(是的,它需要时间来理解事物…BTW我建议你遵循这个渠道和提高你的技能…这不是一个直接的解决你的问题,但你可以考虑使用<代码> UITabeVIEW < /COD>或<代码> uistaVIEWSOUT> UISACKVIEW 在“代码> UISCRelVIEW < /代码>中,将图像添加到StaveVIEW中。这不是对问题的直接解决方案,但您可以考虑使用<代码> UITabeVIEW 或<代码> UistAcVIEW .-)或“<代码> uistaVIEWS/<代码> > <代码> UISCRelVIEW < /代码>,将图像添加到StaveVIEW中。