2015-11-09 53 views
2

我试图做一个UIScrollView包含UIStackView嵌套在里面的几层堆栈视图。我想用自动版式,但有什么不对的我在做什么,我的大脑是越来越炒试图弄明白:iOS 9 StackView里面的ScrollView没有填充屏幕的宽度

import UIKit 

class HomeView: UIView { 

    let looks = sampleLooks 
    let user = sampleUser 
    let streamView: UIStackView = UIStackView(arrangedSubviews: []) 
    let scrollView: UIScrollView = UIScrollView() 

    func makeButtonWithTitle(title: String, image: UIImage?, selector: String, tag: Int) -> UIButton { 
     let button = UIButton(type: .System) 
     button.setImage(image, forState: .Normal) 
     button.tintColor = UIColor.blackColor() 
     switch tag { 
     case 0...10: 
      button.backgroundColor = UIColor(white: 0.98, alpha: 0.8) 
      button.titleLabel?.font = UIFont(name: "HelveticaNeue-Thin", size: 30) 
     default: 
      button.backgroundColor = UIColor(white: 0.90, alpha: 1.0) 
      button.titleLabel?.font = UIFont(name: "HelveticaNeue-Thin", size: 40) 
     } 
     button.setTitle(title, forState: .Normal) 
     button.tag = tag 
     return button 
    } 

    func makeMessageView(senderImage: UIImage, senderHandle: String, text: String) -> UIView { 
     let textView = UILabel() 
     textView.text = text 
     textView.font = UIFont(name: "HelveticaNeue-Thin", size: 20) 
     let senderLabel = UILabel() 
     senderLabel.text = senderHandle 
     textView.font = UIFont(name: "HelveticaNeue-Thin", size: 20) 

     let textStackView = UIStackView(arrangedSubviews:[senderLabel, textView]) 
     textStackView.axis = .Horizontal 
     textStackView.alignment = .Fill 
     textStackView.distribution = .Fill 

     let postView = UIView() 
     postView.addSubview(textStackView) 
     postView.backgroundColor = UIColor(white: 0.98, alpha: 0.8) 

     return postView 
    } 

    required init?(coder:NSCoder) { 
     super.init(coder:coder) 

     self.contentMode = .ScaleToFill 
     self.backgroundColor = UIColor(patternImage: UIImage(named: "background")!) 

     self.streamView.spacing = 20.0 
     self.streamView.translatesAutoresizingMaskIntoConstraints = false 
     self.streamView.axis = .Vertical 
     self.streamView.alignment = .Fill 
     self.streamView.distribution = .FillEqually 

     for look in self.looks { 

      let lookImageView = UIImageView(image: look.photo.photo) 
      lookImageView.contentMode = .ScaleAspectFit 
      lookImageView.clipsToBounds = true 

      let postView = self.makeMessageView(
       look.user.photo.photo, senderHandle: look.user.handle, text: look.post) 

      let likeButton = self.makeButtonWithTitle(
       " Like", image: UIImage(named: "like"), selector: "", tag: 0) 
      let commentButton = self.makeButtonWithTitle(
       " Comment", image: UIImage(named: "SMS"), selector: "", tag: 1) 
      let shareButton = self.makeButtonWithTitle(
       " Share", image: UIImage(named: "upload"), selector: "", tag: 2) 
      let buttonsView = UIStackView(arrangedSubviews: [likeButton, commentButton, shareButton]) 
      buttonsView.distribution = .FillEqually 

      let lookView = UIStackView(arrangedSubviews:[lookImageView, postView, buttonsView]) 
      lookView.axis = .Vertical 
      lookView.distribution = .Fill 
      lookView.alignment = .Fill 
      self.streamView.addArrangedSubview(lookView) 

     } 

     self.scrollView.addSubview(self.streamView) 
     self.scrollView.frame = UIScreen.mainScreen().bounds 
     self.scrollView.showsVerticalScrollIndicator = false 
     self.scrollView.showsHorizontalScrollIndicator = false 
     self.addSubview(self.scrollView) 

    } 

} 

所以,我想这个代码做的是给我一个可滚动的嵌套堆栈,覆盖屏幕的宽度(可以,如果图像被剪切,但我希望它们覆盖屏幕而不失真)。它实际上给了我一个可滚动的图像集,其中第一个图像的宽度(看似)决定了堆栈的宽度。我实际上不确定这是怎么回事,但顶层UIStackView没有覆盖屏幕的宽度。

我认为它与UIScrollView有什么关系没有固有的宽度,所以它内部的堆栈视图决定了它自己的大小。我这样说是因为如果我直接在父视图中放置堆栈视图,它会覆盖显示器,但正如你所期望的那样,没有滚动...

回答

4

你需要在scrollview和它包含的UIStackView,目前你没有。

这三个都足以让内UIStackView滚动视图的大小相同:

  • 滚动视图和UIStackView,滚动视图和UIStackView之间
  • 垂直方向制约它们之间没有空间之间的水平约束,这样你就可以滚动用于滚动视图和UIStackView的UIStackView
  • 相同宽度的整个高度它们之间没有空间,这样的UIStackView将匹配滚动视图宽度

这是代码:

//You already have these two lines: 
//scrollView.addSubview(streamView) 
//streamView.translatesAutoresizingMaskIntoConstraints = false; 
//Add this one too: 
scrollView.translatesAutoresizingMaskIntoConstraints = false; 

scrollView.addConstraints(
    NSLayoutConstraint.constraintsWithVisualFormat("V:|[innerView]|", 
     options: NSLayoutFormatOptions(rawValue:0), 
     metrics: nil, 
     views: ["innerView":streamView])) 

scrollView.addConstraints(
    NSLayoutConstraint.constraintsWithVisualFormat("H:|[innerView]|", 
     options: NSLayoutFormatOptions(rawValue:0), 
     metrics: nil, 
     views: ["innerView":streamView])) 

scrollView.addConstraint(
    NSLayoutConstraint(item: scrollView, 
        attribute: .Width, 
        relatedBy: .Equal, 
        toItem: streamView, 
        attribute: .Width, 
       multiplier: 1.0, 
        constant: 0)) 

或者,你可以与嵌入您的视图中滚动视图的方法延长的UIView:

extension UIView { 

    func embedInScrollView()->UIView{ 
     let cont=UIScrollView() 

     self.translatesAutoresizingMaskIntoConstraints = false; 
     cont.translatesAutoresizingMaskIntoConstraints = false; 
     cont.addSubview(self) 
     cont.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[innerView]|", options: NSLayoutFormatOptions(rawValue:0),metrics: nil, views: ["innerView":self])) 
     cont.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[innerView]|", options: NSLayoutFormatOptions(rawValue:0),metrics: nil, views: ["innerView":self])) 
     cont.addConstraint(NSLayoutConstraint(item: self, attribute: .Width, relatedBy: .Equal, toItem: cont, attribute: .Width, multiplier: 1.0, constant: 0)) 
     return cont 
    } 
} 

而且使用这种方式:

let scrollView = streamView.embedInScrollView() 

编辑:修正了第一个片段中的最后一个约束。

+0

Thx @uraimo,我会试试。 – gred

+0

它应该工作,我有一个应用程序,基本上你发布相同的结构。 –

+0

由于该代码: scrollView.addConstraint( NSLayoutConstraint(项目:streamView, 属性:.WIDTH, relatedBy:.Equal, toItem:滚动视图, 属性:.WIDTH, 乘数:1.0, 常数: 0)) 我基本上在那里。这不是你发布的内容('toItem:scrollView'而不是'toItem:streamView',但我认为这就是你的意思),但是谢谢你的推动! – gred

相关问题