奇怪的iOS 8自动布局问题

时间:2014-10-15 15:04:03

标签: ios xamarin.ios ios8 autolayout

我有一个自定义的UITableViewCell。

  1. 最初,在单元格的内容视图中设置了一些子视图和一些自动布局约束。一切都按预期工作。
  2. 然后我以编程方式更改(删除/添加)一些子视图并完全重置约束(删除所有,然后添加新约束)。之后,刷新包含单元格的UITable(重新计算行的高度),并在单元格上显式调用 setNeedsUpdateContraints updateConstraintsIfNeeded
  3. 以下是重现该问题的完整代码。它在C#(Xamarin)中,但它很容易理解。 Here is在Swift中的代码几乎相同。

    public class TableViewController : UITableViewController
    {
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
    
            var source = new TableSource(TableView);
    
            var updateButton = new UIBarButtonItem("Update", UIBarButtonItemStyle.Plain, (s, args) => source.DoUpdate());
            NavigationItem.RightBarButtonItem = updateButton;
    
            TableView.Source = source;
            TableView.ReloadData();
        }
    }
    
    public class TableSource : UITableViewSource
    {
        private readonly UITableView _tableView;
        private readonly TableCell _cell;
    
        public TableSource(UITableView tableView)
        {
            _tableView = tableView;
            _cell = new TableCell();
        }
    
        public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
        {
            return _cell;
        }
    
        public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
        {
            return 55.0f;
        }
    
        public override int RowsInSection(UITableView tableview, int section)
        {
            return 1;
        }
    
        public void DoUpdate()
        {
            _cell.DoUpdate();
            _tableView.ReloadData();
        }
    }
    
    public class TableCell : UITableViewCell
    {
        private UILabel _label;
    
        public TableCell()
        {
            DoUpdate();
        }
    
        public void DoUpdate()
        {
            foreach (var subview in ContentView.Subviews)
            {
                subview.RemoveFromSuperview();
            }
    
            _label = new UILabel {Text = "Text here"};
            ContentView.Add(_label);
    
            foreach (var subview in ContentView.Subviews)
            {
                subview.TranslatesAutoresizingMaskIntoConstraints = false;
            }
    
            ContentView.RemoveConstraints(ContentView.Constraints);
            ContentView.AddConstraints(
                new[]
                {
                    NSLayoutConstraint.Create(_label, NSLayoutAttribute.Left, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Left, 1.0f, 15.0f),
                    NSLayoutConstraint.Create(_label, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1.0f, 100.0f),
                    NSLayoutConstraint.Create(_label, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Top, 1.0f, 20.0f),
                    NSLayoutConstraint.Create(_label, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Bottom, 1.0f, -20.0f)
                });
        }
    }
    

    在发布时一切正常:

    enter image description here

    但点击“更新”按钮(重置子视图和约束)后:

    iOS 7 上没有任何变化(按预期工作)。

    iOS 8 布局上无法正常工作。看起来它失去了一些约束来定义一些子视图和单元格的内容视图边界之间的边距:

    enter image description here

    为什么会这样?它看起来像iOS自动布局系统中的一个错误。

1 个答案:

答案 0 :(得分:3)

是的,iOS 8 AutoLayout现在真的定义了边距。

<强>已更新

通过这样做来打破contentView约束:

ContentView.RemoveConstraints(ContentView.Constraints);

此行与其父级断开contentView关系。删除此行。