2014-10-15 3 views
1

У меня есть пользовательский UITableViewCell.Странный iOS 8 автоматический макет вопрос

  1. Изначально некоторые частичные представления и некоторые ограничения автоматической компоновки задаются в представлении содержимого ячейки. Все работает так, как ожидалось.
  2. Затем я программно меняю (удаляю/добавляю) некоторые подвид и полностью восстанавливаю ограничения (удаляю все, а затем добавляю новые ограничения). После этого UITable, содержащий ячейку, обновляется (высота строки пересчитывается) и setNeedsUpdateContraints, updateConstraintsIfNeeded также явно называются ячейкой.

Полный текст, чтобы воспроизвести проблему. Это на 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

Но после нажатия кнопки Update (сброс подвидов и ограничений):

На IOS 7 ничего не меняется (работает как ожидалось) ,

руководство по эксплуатации iOS 8 не работает должным образом. Похоже, что она теряет некоторые ограничения, определяющие поля между некоторыми из подвидов и просмотра содержимого клеточных границ:

enter image description here

Любые идеи, почему это происходит? Это похоже на ошибку в системе автоматической компоновки iOS.

+1

Вы внедряете метод heightForRowAtIndexPath? Снимок экрана или рисунок были бы хороши, чтобы точно понять проблему макета, с которой вы столкнулись. – Shank

+0

Да, реализуя heightForRowAtIndexPath. Добавлены скриншоты, спасибо. – alexey

+0

Пожалуйста, покажите свой код, который создает ограничения. – matt

ответ

3

Да, iOS 8 AutoLayout сейчас действительно определяет поля.

ОБНОВЛЕНО

Вы нарушаете contentView ограничения, делая это:

ContentView.RemoveConstraints(ContentView.Constraints); 

Эта линия разбивает contentView отношения с его родителем. Удалите эту строку.

+0

Все ограничения создаются в коде, поэтому я не использую ограничения по границам. – alexey

+0

@alexey, хотя '' - [subview] - | 'дает вам ** относительно поля **. Вместо этого попробуйте '| [subview] |'. И проверьте свойство 'layoutMargins'' UIView'. – orkenstein

+0

Я предполагаю, что описание строки содержит '-'s из-за реализации Xamarin. Я точно определяю все ограничения, используя NSLayoutAttribute и никогда не использую новые атрибуты типа iOS 8. – alexey

Смежные вопросы