iOS UITableViewCell水平滚动带有自动布局的子视图

时间:2014-11-20 22:10:25

标签: ios swift autolayout

我正在尝试构建一个表格视图,其中的单元格包含水平滚动的卡片。我创建了一个简单的演示应用程序,并在一定程度上成功实现了使用自动布局...的版本。一个(我认为是最终的)问题仍然存在。卡片的垂直尺寸有问题。

的TableView:

class MultiCardTableViewController: UITableViewController {
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 12
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("CardCell", forIndexPath: indexPath) as CardCell

        //since these cells are re-used, we have to clear out the previous dynamic subviews
        for subView in cell.scrollContentView.subviews { subView.removeFromSuperview() }

        var card = NSBundle.mainBundle().loadNibNamed("CardView", owner: self, options: nil)[0] as CardView
        //Turn this off because subviews of UIScrollView use autoresizing mask by default, which conflict with Auto-Layout constraints
        card.setTranslatesAutoresizingMaskIntoConstraints(false)
        cell.scrollContentView.addSubview(card)

        var card2 = NSBundle.mainBundle().loadNibNamed("CardView", owner: self, options: nil)[0] as CardView
        //Turn this off because subviews of UIScrollView use autoresizing mask by default, which conflict with Auto-Layout constraints
        card2.setTranslatesAutoresizingMaskIntoConstraints(false)
        cell.scrollContentView.addSubview(card2)

        //Add bottom margin to the last cell (for consistency)
        //Add vertical constraints (standard margins) for each card
        var constraints = NSLayoutConstraint.constraintsWithVisualFormat("V:|-[card]|", options: nil, metrics: nil, views: ["card": card])
        constraints = NSLayoutConstraint.constraintsWithVisualFormat("V:|-[card2]|", options: nil, metrics: nil, views: ["card2": card2])
        //Add horizontal constraints that tie the cards together, and to the super view
        constraints += NSLayoutConstraint.constraintsWithVisualFormat("H:|-[card]-(16)-[card2]-|", options: nil, metrics: nil, views: ["card": card, "card2": card2])
        //Add horizontal constraint that disambiguates individual card width
        constraints += NSLayoutConstraint.constraintsWithVisualFormat("H:[card(==card2)]", options: nil, metrics: nil, views: ["card": card, "card2": card2])
        cell.scrollContentView.addConstraints(constraints)

        //Set the scrollview content horizontal size constraint to double the window width (1 window width for each card
        cell.contentWidthConstraint.constant = self.tableView.frame.width * 2

        return cell
    }
}

细胞:

class CardCell: UITableViewCell
{
    @IBOutlet weak var scrollView: UIScrollView!
    //A content view directly inside of the scroll view, constrained to super view on all sides, as well as height & width
    @IBOutlet weak var scrollContentView: UIView!
    //A reference to the width constraint for the scrollContentView
    @IBOutlet weak var contentWidthConstraint: NSLayoutConstraint!
}

CardView.xib:

CardView Nib File

结果:

Horizontal Scroll Bug

水平间距和大小调整是正确的,但似乎垂直约束不足或不正确。我觉得很难相信,因为它们很简单。每张卡都有垂直约束:V:|-[card]|

我尝试在卡片上添加明确的高度限制,类似于宽度,但这也不会产生正确的结果:V:[card(==card2)]

显式垂直高度约束的结果:

Horizontal Scroll Bug 2

我已经绞尽脑汁好几天......我错过了什么?

修改:为示例项目添加了github source link

2 个答案:

答案 0 :(得分:2)

幸运的是,我的代码示例中的问题是一个小问题:

constraints = NSLayoutConstraint.constraintsWithVisualFormat("V:|-[card2]|", options: nil, metrics: nil, views: ["card2": card2])

是覆盖先前的约束数组,而应该添加到它:

constraints += NSLayoutConstraint.constraintsWithVisualFormat("V:|-[card2]|", options: nil, metrics: nil, views: ["card2": card2])

答案 1 :(得分:1)

导入UIKit

类ViewController:UIViewController,UITableViewDelegate,UITableViewDataSource {

var tableviwe:UITableView?

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.tableviwe = UITableView(frame: self.view!.bounds)
    self.tableviwe!.delegate = self
    self.tableviwe!.dataSource = self;
    self.tableviwe?.backgroundColor = UIColor.redColor()
    let angle:CGFloat = CGFloat(M_PI_2);//double angle;
    self.tableviwe?.transform = CGAffineTransformMakeRotation(angle)
    self.view?.addSubview(self.tableviwe!)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

//UITableViewDelegate
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let alert = UIAlertView()
    alert.title = "Alert"
    alert.message = NSString(format: "%@ %d", "My hit ", indexPath.row)
    alert.addButtonWithTitle("Ok")
    alert.show()
}
//UITableViewDataSource
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1000
}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat{
    return 200.0
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "channel")
    cell.textLabel?.text = NSString(format: "%@ %d", "hello my friend", indexPath.row)
    let angle:CGFloat = CGFloat(M_PI_2);// double angle;
    cell.contentView.transform = CGAffineTransformMakeRotation(-angle)
    return cell
}