Reputation: 639
I came across an interesting problem that only arises on iPhone 6/6+ and iPad mini with retina display.
In the following code:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if(self.seeMoreContents)
{
BOOL isText = [self.seeMoreContents isText];
self.imageView.hidden = isText;
[self.textView removeConstraint:self.textHeightConstraint];
[self.textWrapperView removeConstraint:self.textWrapperHeightConstraint];
if (!isText)
{
__weak FCSeeMoreViewController *weakSelf = self;
[self.imageView setImageByFlashcardSide:self.seeMoreContents completion:^(BOOL preloaded){
weakSelf.imageView.center = CGPointMake(weakSelf.view.frame.size.width / 2, weakSelf.view.frame.size.height / 2);
[weakSelf.scrollView setContentOffset:CGPointMake(0, 0)];
}];
}
}
}
- (void)viewDidLayoutSubviews
{
if ([self.seeMoreContents isText])
{
self.textView.text = self.seeMoreContents.text;
self.textView.font = self.fontForContents;
self.textWrapperView.hidden = NO;
[self.textView sizeToFit];
CGFloat height = self.textView.frame.size.height;
[self updateView:self.textView withConstraint:self.textHeightConstraint ofValue:height];
[self updateView:self.textWrapperView withConstraint:self.textWrapperHeightConstraint ofValue:height + self.wrapperMargin];
[self.scrollView setContentSize:CGSizeMake(self.textView.frame.size.width, height + self.scrollTextMargin)];
[self.scrollView setContentOffset:CGPointMake(0, -self.wrapperScrollVerticalConstraint.constant)];
}
[super viewDidLayoutSubviews];
}
- (void)updateView:(UIView*)view withConstraint:(NSLayoutConstraint*)constraint ofValue:(CGFloat)value
{
constraint.constant = value;
[view addConstraint:constraint];
}
By the time the two messages of udpateView
get passed, the constraints have become nil. I could attribute this to weird garbage collection behavior, but it only happens on iPhone 6/6+ and mini retina iPad.
I have changed this whole controller to work better and to not to programmatically set constraints, but I want to know how/why this can happen on specific devices. Any insight would be greatly appreciated.
Upvotes: 1
Views: 146
Reputation: 12615
Override this method in your UIViewController to detect changing of 'traits':
func willTransitionToTraitCollection(_ newCollection: UITraitCollection,
withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
This is where you intercept constraint changes to get them at the right time, otherwise it's a race and your code can lose.
I suspect not using that function to get the timing right may be why you are not seeing consistent results. I bumped into the same kind of problem awhile back - not finding constraints that should have been there when I went looking for them.
Another thing to consider about mysterious constraints appearing and disappearing, of course, is UIView's
translatesAutoresizingMaskIntoConstraints
property, which if true (the default), causes iOS to dynamically create constraints, besides whatever you may have created programmatically or created in Interface Builder. And I have noticed some iOS generated constraints can disappear in different devices and orientations, as the iOS implementation that applies and removes such constraints is a black box.
Upvotes: 1