2015-01-07 6 views
1

Я работаю над проектом, который должен поддерживать как iOS 8, так и iOS 7.1. Прямо сейчас у меня проблема, которая появляется только на iOS 7.1, но работает правильно на iOS 8. У меня есть ViewController, который содержит табличное представление и пользовательский вид в таблицеHeaderView. Я отправлю код следующим образом. Все ограничения добавляются программно.iOS 7.1 UITableView layoutSubviews issue

// Просмотр контроллера.

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.commentsArray = [NSMutableArray new]; 

    [self.commentsArray addObject:@"TEST"]; 
    [self.commentsArray addObject:@"TEST"]; 
    [self.commentsArray addObject:@"TEST"]; 
    [self.commentsArray addObject:@"TEST"]; 
    [self.commentsArray addObject:@"TEST"]; 
    [self.commentsArray addObject:@"TEST"]; 

    [self.view addSubview:self.masterTableView]; 

    self.masterTableView.tableHeaderView = self.detailsView; 

    [self.view setNeedsUpdateConstraints]; 


} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self.view layoutIfNeeded]; 
} 


//Table view getter 
- (UITableView *)masterTableView 
{ 
    if(!_masterTableView) 
    { 
    _masterTableView = [UITableView new]; 
    _masterTableView.translatesAutoresizingMaskIntoConstraints = NO; 

    _masterTableView.backgroundColor    = [UIColor greyColor]; 

    _masterTableView.delegate      = self; 
    _masterTableView.dataSource      = self; 

    _masterTableView.separatorStyle     = UITableViewCellSeparatorStyleNone; 
    _masterTableView.showsVerticalScrollIndicator = NO; 
    _masterTableView.separatorInset     = UIEdgeInsetsZero; 

    } 

    return _masterTableView; 
} 

-(void)updateViewConstraints 
{ 
NSDictionary *views = @{ 
     @"table"  : self.masterTableView, 
     @"details"  : self.detailsView, 
}; 


    NSDictionary *metrics = @{ 
          @"width" : @([UIScreen mainScreen].applicationFrame.size.width) 
          }; 
    //Table view constraints 
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[table]-0-|" options:0 metrics:0 views:views]]; 
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[table]-0-|" options:0 metrics:0 views:views]]; 

    //Details View 
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[details(width)]-0-|" options:0 metrics:metrics views:views]]; 
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[details]-0-|" options:0 metrics:metrics views:views]]; 

} 


//Details View Getter 
- (DetailsView *)detailsView 
{ 
    if(!_detailsView) 
    { 

    _detailsView = [[DetailsView alloc]initWithFrame:CGRectMake(0, 0, 0, 100)]; 
    _detailsView.backgroundColor = [UIColor orangeColor]; 

    return _detailsView; 
} 

Теперь детали просмотра содержит некоторые основные подвидов, которые все вытекают из UIView и детали просмотра само вытекает из более общего суперкласса. Я отправлю код следующим образом.

//Parent View 
@interface ParentView(): UIView 

- (instancetype)init 
{ 
    self = [super init]; 

    if (self) 
    { 
    [self setupViews]; 
    } 

    return self; 
} 


- (void)setupViews 
{ 
    [self addSubview:self.publishedTimeView]; 
} 

- (void)updateConstraints 
{ 
    NSDictionary *views = @{ 
          @"time"   : self.publishedTimeView, 
          }; 


    // Header with published video time 
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[time]-10-|" options:0 metrics:0 views:views]]; 
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[time(11)]" options:0 metrics:0 views:views]]; 

    [super updateConstraints]; 
} 

//Getter for the timePublished view added to the detail view. Will not post all its related code for //the sake of brevity. 
- (TimePublishedDetailView *)publishedTimeView 
{ 
    if(!_publishedTimeView) 
    { 
    _publishedTimeView = [TimePublishedDetailView new]; 
    _publishedTimeView.translatesAutoresizingMaskIntoConstraints = NO; 
    } 

    return _publishedTimeView; 
} 

//Child View (or the detailsView) of the view controller. 

@interface DetailsView : ParentView 


@implementation RecordingDetailsView 

- (void)updateConstraints 
{ 
    NSDictionary *views = @{ 
          @"time"   : self.publishedTimeView, 
          }; 

    //Vertical alignment of all views 

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[time]" options:0 metrics:nil views:views]]; 

    [super updateConstraints]; 

} 


- (void)setModel:(DetailViewModel *)model 
{ 
    self.publishedTimeView.date = model.dateTime; 

    [self setNeedsUpdateConstraints]; 
    [self layoutSubviews]; 
} 

Сейчас на прошивке 8 это выглядит следующим образом: enter image description here

Однако на прошивке 7.1 это произойдет сбой с этим сообщением об ошибке:

«Исключение: Автоматическая раскладка по-прежнему требуется после выполнения -layoutSubviews. Реализация UITableView -layoutSubviews должна быть вызвана супер »

Я искал это и играл с кодом в моих вызовах макета, чтобы увидеть, могу ли я исправить проблему, но до сих пор был nsuccessful. Если бы кто-нибудь мог написать несколько советов или советов о том, как исправить это, я бы очень признателен.

+0

Любая причина, по которой я что-то делаю? Можете ли вы быть конкретными? – zic10

+0

Извините, мое редактирование не обновилось! Вы пробовали делать вещи в разных жизненных циклах зрения? Вы можете получить больше идеи о том, что происходит – Alex

+0

Да, я провел довольно много испытаний и экспериментов с этим. Пошел даже до того, как комментировал timePublishedView, и это все еще происходит только на iOS 7. – zic10

ответ

2

Я знаю, что этот вопрос старый, но в последнее время я столкнулся с подобной проблемой, и после многих попыток Google, попыток и сбоев я сделал это с помощью this answer и нескольких изменений.

Просто добавьте эту категорию в свой проект и позвоните по номеру [UITableView fixLayoutSubviewsMethod]; только один раз (рекомендую внутри AppDelegate).

#import <objc/runtime.h> 
#import <objc/message.h> 

@implementation UITableView (FixUITableViewAutolayoutIHope) 

+ (void)fixLayoutSubviewsMethod 
{ 
    Method existing = class_getInstanceMethod(self, @selector(layoutSubviews)); 
    Method new = class_getInstanceMethod(self, @selector(_autolayout_replacementLayoutSubviews)); 

    method_exchangeImplementations(existing, new); 
} 

- (void)_autolayout_replacementLayoutSubviews 
{ 
    [super layoutSubviews]; 
    [self _autolayout_replacementLayoutSubviews]; // not recursive due to method swizzling 
    [super layoutSubviews]; 
} 

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