2013-02-11 3 views
3

Это мое первое сообщение в Stack Overflow, и я новичок iOS, поэтому, пожалуйста, несите меня!UIScrollView, показывающий только часть UIView после вращения

У меня есть пример приложения, в котором у меня есть три UIViews (headerView, scrollViewContainer и bodyView) в родительском UIView (topView), и все эти представления создаются в коде. TopView добавляется в UIScrollView (pageScrollView), созданный в раскадровке.

страницаScrollView заполняет весь экран iPhone, и я использовал Autolayout. Приложение содержит только ViewController.h и сопроводительный .m-файл, показанный ниже, плюс Appdelegate.x. Я думаю, что я использовал шаблон приложения с одним представлением для начала. Я использую iOS 6 и Xcode 4.6, но я также попробовал 4.5.

Я попытался удалить как можно больше другого кода, который не имеет отношения к этой проблеме.

Проблема: Когда приложение запускается, оно отображает все его виды правильно, а scrollView позволяет просматривать все три вида по назначению. Но после поворота на пейзаж, scrollView каким-то образом смещает содержимое. Например: Оставайтесь наверху и вращайте = содержимое выглядит нормально, но немного прокручивайте и вращайте, чтобы верхняя часть содержимого не отображалась.

То, что я пробовал: я искал в сети помощь, но я не нашел ничего, что могло мне помочь. Я добавил регистрацию различных данных, таких как origin и contentSize, а также попытался установить некоторые из них, но без каких-либо успехов. Я также использовал 'po [[UIWindow keyWindow] _autolayoutTrace]', чтобы гарантировать, что ограничения в порядке.

Я не вижу, что я делаю неправильно. Есть ли очевидные вещи, отсутствующие в моем коде?

Заранее благодарен!

Вот ViewController.m:

#import "ViewController.h" 

@interface ViewController() 
{ 
    UIView *topView; 
    UIView *headerView; 
    UIView *bodyView; 
    UIView *scrollViewContainer; 

    UIInterfaceOrientation newOrientation; 
    CGFloat bodyViewHeight; 
    CGSize newBounds; 
    float pictureScrollHeight; 
} 
@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    newBounds = [self sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation]; 

    newOrientation = [UIApplication sharedApplication].statusBarOrientation; 
    bodyViewHeight = 1200; // The height of the body view varies in size depending on orientation 

    self.pageScrollView.translatesAutoresizingMaskIntoConstraints = NO; 

    topView = [[UIView alloc] init]; 
    [topView setBackgroundColor:[UIColor clearColor]]; 
    topView.translatesAutoresizingMaskIntoConstraints = NO; 
    [self.pageScrollView addSubview:topView]; 

    headerView = [[UIView alloc] init]; 
    [headerView setBackgroundColor:[UIColor redColor]]; 
    headerView.translatesAutoresizingMaskIntoConstraints = NO; 
    [topView addSubview:headerView]; 

    scrollViewContainer = [[UIView alloc] init]; 
    [scrollViewContainer setBackgroundColor:[UIColor blueColor]]; 
    scrollViewContainer.translatesAutoresizingMaskIntoConstraints = NO; 
    [topView addSubview:scrollViewContainer]; 

    bodyView = [[UIView alloc] init]; 
    [bodyView setBackgroundColor:[UIColor greenColor]]; 
    bodyView.translatesAutoresizingMaskIntoConstraints = NO; 
    [topView addSubview:bodyView]; 

    [self updateViewConstraints]; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
} 

- (void)updateViewConstraints 
{ 
    [super updateViewConstraints]; 

    // Remove old constraints 
    [self.view removeConstraints:self.view.constraints]; 
    [self.pageScrollView removeConstraints:self.pageScrollView.constraints]; 
    [topView removeConstraints:topView.constraints]; 
    [scrollViewContainer removeConstraints:scrollViewContainer.constraints]; 

    if ((newOrientation == UIDeviceOrientationLandscapeLeft) || (newOrientation == UIDeviceOrientationLandscapeRight)) { 
     pictureScrollHeight = 300; 
    } else { 
     pictureScrollHeight = 203; 
    } 

    [headerView setNeedsDisplay]; 
    [bodyView setNeedsDisplay]; 

    CGFloat topViewHeight = bodyViewHeight + 55 + pictureScrollHeight; 

    //self.pageScrollView = _pageScrollView 
    NSDictionary *viewsDict = NSDictionaryOfVariableBindings(_pageScrollView, topView, headerView, bodyView, scrollViewContainer); 
    NSDictionary *metricsDict = @{@"topViewHeight": [NSNumber numberWithFloat:topViewHeight], 
            @"newBoundsWidth": [NSNumber numberWithFloat:newBounds.width], 
            @"pictureScrollHeight": [NSNumber numberWithFloat:pictureScrollHeight], 
            @"bodyViewHeight": [NSNumber numberWithFloat:bodyViewHeight]}; 

    // pageScrollView - child to self.view 
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_pageScrollView]-0-|" options:0 metrics:nil views:viewsDict]]; 
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[_pageScrollView]-0-|" options:0 metrics:nil views:viewsDict]]; 

    // topView - child to pageScrollView 
    [self.pageScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[topView(newBoundsWidth)]-0-|" options:0 metrics:metricsDict views:viewsDict]]; 
    [self.pageScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[topView(topViewHeight)]-0-|" options:0 metrics:metricsDict views:viewsDict]]; 

    // headerView - child to topView 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[headerView]-0-|" options:0 metrics:nil views:viewsDict]]; 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[headerView(55.0)]" options:0 metrics:nil views:viewsDict]]; 

    // scrollViewContainer - child to topView 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[scrollViewContainer]-0-|" options:0 metrics:nil views:viewsDict]]; 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[headerView]-0-[scrollViewContainer(pictureScrollHeight)]" options:0 metrics:metricsDict views:viewsDict]]; 

    // bodyView - child to topView 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[bodyView]-0-|" options:0 metrics:nil views:viewsDict]]; 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[scrollViewContainer]-0-[bodyView(bodyViewHeight)]-0-|" options:0 metrics:metricsDict views:viewsDict]]; 
} 


- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{ 
    newOrientation = toInterfaceOrientation; 
    newBounds = [self sizeInOrientation:toInterfaceOrientation]; 
} 


-(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation 
{ 
    CGSize size = [UIScreen mainScreen].bounds.size; 
    UIApplication *application = [UIApplication sharedApplication]; 
    if (UIInterfaceOrientationIsLandscape(orientation)) 
    { 
     size = CGSizeMake(size.height, size.width); 
    } 
    if (application.statusBarHidden == NO) 
    { 
     size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height); 
    } 
    return size; 
} 

@end 

ответ

1

Прежде всего, вам не нужно воссоздавать все ограничения в методе -updateViewConstraints. Вам нужно просто обновить их в этом месте. Для достижения вашей цели выполните следующие действия:

  1. Создайте свои ограничения только один раз. Например, в методе -setupConstraints. И держите ссылку на те, которые необходимо обновить. См. Код ниже.
  2. В методе -updateViewConstraints просто обновлять верхние и вертикальные ограничения высоты и ширины для scrollViewContainer.

Вот ViewController.m должен выглядеть следующим образом:

#import "ViewController.h" 

@interface ViewController() 
@property (nonatomic, strong) IBOutlet UIScrollView* pageScrollView; 
@property (nonatomic, strong) NSLayoutConstraint* pictureHeightConstraint; 
@property (nonatomic, strong) NSLayoutConstraint* topViewWidthConstraint; 
@property (nonatomic, strong) NSLayoutConstraint* topViewHeightConstraint; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    newBounds = [self sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation]; 

    newOrientation = [UIApplication sharedApplication].statusBarOrientation; 
    bodyViewHeight = 1200; // The height of the body view varies in size depending on orientation 

    self.pageScrollView.translatesAutoresizingMaskIntoConstraints = NO; 

    topView = [[UIView alloc] init]; 
    [topView setBackgroundColor:[UIColor clearColor]]; 
    topView.translatesAutoresizingMaskIntoConstraints = NO; 
    [self.pageScrollView addSubview:topView]; 

    headerView = [[UIView alloc] init]; 
    [headerView setBackgroundColor:[UIColor redColor]]; 
    headerView.translatesAutoresizingMaskIntoConstraints = NO; 
    [topView addSubview:headerView]; 

    scrollViewContainer = [[UIView alloc] init]; 
    [scrollViewContainer setBackgroundColor:[UIColor blueColor]]; 
    scrollViewContainer.translatesAutoresizingMaskIntoConstraints = NO; 
    [topView addSubview:scrollViewContainer]; 

    bodyView = [[UIView alloc] init]; 
    [bodyView setBackgroundColor:[UIColor greenColor]]; 
    bodyView.translatesAutoresizingMaskIntoConstraints = NO; 
    [topView addSubview:bodyView]; 

    [self setupConstraints]; 
} 


- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
} 

- (void)setupConstraints { 
    // Remove old constraints 
    [self.view removeConstraints:self.view.constraints]; 
    [self.pageScrollView removeConstraints:self.pageScrollView.constraints]; 
    [topView removeConstraints:topView.constraints]; 
    [scrollViewContainer removeConstraints:scrollViewContainer.constraints]; 

    if ((newOrientation == UIDeviceOrientationLandscapeLeft) || (newOrientation == UIDeviceOrientationLandscapeRight)) { 
     pictureScrollHeight = 300; 
    } else { 
     pictureScrollHeight = 203; 
    } 

    [headerView setNeedsDisplay]; 
    [bodyView setNeedsDisplay]; 

    CGFloat topViewHeight = bodyViewHeight + 55 + pictureScrollHeight; 

    //self.pageScrollView = _pageScrollView 
    NSDictionary *viewsDict = NSDictionaryOfVariableBindings(_pageScrollView, topView, headerView, bodyView, scrollViewContainer); 

    // pageScrollView - child to self.view 
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_pageScrollView]-0-|" options:0 metrics:nil views:viewsDict]]; 
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0- [_pageScrollView]-0-|" options:0 metrics:nil views:viewsDict]]; 

    // topView - child to pageScrollView 
    [self.pageScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[topView]-0-|" options:0 metrics:nil views:viewsDict]]; 
    [self.pageScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[topView]-0-|" options:0 metrics:nil views:viewsDict]]; 
    NSLayoutConstraint* topViewWidthConstraint = [NSLayoutConstraint constraintWithItem:topView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:newBounds.width]; 
    self.topViewWidthConstraint = topViewWidthConstraint; 
    [topView addConstraint:self.topViewWidthConstraint]; 
    NSLayoutConstraint* topViewHeightConstraint = [NSLayoutConstraint constraintWithItem:topView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:topViewHeight]; 
    self.topViewHeightConstraint = topViewHeightConstraint; 
    [topView addConstraint:self.topViewHeightConstraint]; 

    // headerView - child to topView 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[headerView]-0-|" options:0 metrics:nil views:viewsDict]]; 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[headerView(55.0)]" options:0 metrics:nil views:viewsDict]]; 

    // scrollViewContainer - child to topView 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[scrollViewContainer]-0-|" options:0 metrics:nil views:viewsDict]]; 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[headerView]-0-[scrollViewContainer]" options:0 metrics:nil views:viewsDict]]; 
    NSLayoutConstraint* pictureHeightConstraint = [NSLayoutConstraint constraintWithItem:scrollViewContainer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:pictureScrollHeight]; 
    self.pictureHeightConstraint = pictureHeightConstraint; 
    [scrollViewContainer addConstraint:self.pictureHeightConstraint]; 

    // bodyView - child to topView 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[bodyView]-0-|" options:0 metrics:nil views:viewsDict]]; 
    [topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V: [scrollViewContainer]-0-[bodyView]-0-|" options:0 metrics:nil views:viewsDict]]; 
} 

- (void)updateViewConstraints 
{ 
    [super updateViewConstraints]; 
    if ((newOrientation == UIDeviceOrientationLandscapeLeft) || (newOrientation == UIDeviceOrientationLandscapeRight)) { 
     pictureScrollHeight = 300; 
    } else { 
     pictureScrollHeight = 203; 
    } 

    CGFloat topViewHeight = bodyViewHeight + 55 + pictureScrollHeight; 
    self.pictureHeightConstraint.constant = pictureScrollHeight; 
    self.topViewHeightConstraint.constant = topViewHeight; 
    self.topViewWidthConstraint.constant = newBounds.width; 
    [self.pageScrollView setNeedsUpdateConstraints]; 
} 


- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{ 
    newBounds = [self sizeInOrientation:toInterfaceOrientation]; 
} 


-(CGSize)sizeInOrientation:(UIInterfaceOrientation)orientation 
{ 
    CGSize size = [UIScreen mainScreen].bounds.size; 
    UIApplication *application = [UIApplication sharedApplication]; 
    if (UIInterfaceOrientationIsLandscape(orientation)) 
    { 
     size = CGSizeMake(size.height, size.width); 
    } 
    if (application.statusBarHidden == NO) 
    { 
     size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height); 
    } 
    return size; 
} 


@end 

ScrollView вычисляет его размер контента автоматически в зависимости от подвиды ограничений, добавленных в него. Конечно, он работает только в режиме автозапуска.

+0

Mark, Спасибо, что нашли время, чтобы помочь мне - ваш пример отлично работает! Не проверяя свой код и просто полагаясь на свой пост здесь, вы имеете в виду, что проблема заключалась в том, что я каждый раз создавал ограничения? Большое спасибо! – mberg

+0

Наверное, да. Просмотр прокрутки немного сложнее. У меня нет точного ответа. Я просто удалил ненужные вещи. –

0

Проверить автоматическое изменение размера маски.

+0

Не авторезистентно Маска только для неавтоматического отключения? Во всяком случае, я добавил его в viewDidLoad, но это не имело никакого значения. – mberg

0

Похоже, что вы ничего не делаете с новыми шагами в willRotateToInterfaceOrientation. Не следует вызывать метод updateView после получения новых границ.

+0

При очистке моего кода я случайно удалил «newOrientation = toInterfaceOrientation»; от willRotateTointerfaceOrientation, поэтому я обновил свой пост, чтобы отразить это. Однако код по-прежнему не работает. – mberg

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