IOS Automatic Layout-UIStackPanel and UIGridPanel (4), ios Automatic Layout

Source: Internet
Author: User

IOS Automatic Layout-UIStackPanel and UIGridPanel (4), ios Automatic Layout

Why is the automatic layout of scrollview difficult?

The Automatic Layout of scrollview is nothing more than the Automatic Layout of subviews in scrollview. However, the automatic layout of subviews in scrollview is not determined by the height and width of scrollview, but by the contentSize of scrollview. This leads to a problem, even if the height and width of the scrollview change, the height and width of the subviews in the scrollview are not affected as long as the contentSize remains unchanged. NSLayoutConstraint, which implements automatic layout, cannot automatically layout the contentSize attribute of scrollview. Therefore, it is impossible to use NSLayoutConstraint to automate the layout of the scrollview.

Here we will use another method. In fact, scrollview is usually used for upper and lower scrolling or left-side scrolling. There are few situations where both upper and lower scrolling and left-side scrolling exist. Now we assume that the scrollview of our automatic layout is scroll up and down. In the horizontal direction, the width of subviews is always the same as that of scrollview. Can this scenario be implemented? We can immediately think of this scenario as long as we can use NSLayoutConstraint to bind the width of subviews to the width of scrollview.

    UIScrollView *scroll=[[UIScrollView alloc] init];    scroll.backgroundColor=[UIColor blueColor];    scroll.isBindSizeToSuperView=YES;    [self.view addSubview:scroll];    [scroll setContentSize:CGSizeMake(100, 1000)];        UILabel *label = [[UILabel alloc] initWithSize:CGSizeMake(100, 50)];    label.backgroundColor = [UIColor blackColor];    label.textColor=[UIColor whiteColor];    label.font=[UIFont systemFontOfSize:12];    label.text = @"Label1";    label.translatesAutoresizingMaskIntoConstraints=NO;    label.textAlignment = NSTextAlignmentCenter;    [scroll addSubview:label];    [scroll addConstraint:[NSLayoutConstraint constraintWithItem:label                                                       attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:scroll attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0]];

We found that this could be done! Don't worry. Are you trying to add another subview? You will find that although using this method can make the width of subviews consistent with that of scrollview, the layout cannot be arranged in the vertical direction. Why?

The problem is that we set no for the translatesAutoresizingMaskIntoConstraints attribute. Why do we need to set no? As long as we use automatic layout, or more broadly speaking, as long as we use NSLayoutConstraint, we must set this attribute to no. Once no is set, the position and size of the view can only be achieved through NSLayoutConstraint. Speaking of this, those who have read the first three blogs can think of it. Isn't there a UIStackPanel that can implement such a function? Yes. We can use it directly, add uiStackpanel as not subview to scrollView, and add subviews to stackpanel as they were originally added to scrollvew. In this way, the above scenarios can be achieved. But there is still a problem, that is, the stackpanel width can be bound to the width of scrollview, but what about the height? The height must be bound to the height of contentSize. To achieve this, we need to use the KVO Technology of IOS to obtain the contentSize attribute change event of scrollview, and then bind it again. In this way, the above requirements can be fully realized.

To encapsulate the above implementation process, we added a bindToScrollView method in UIPanel.

NSString * const KVCUIPanelString_ContentSize = @ "scrollView_ContentSize";-(void) bindToScrollView :( UIScrollView *) scrollView {_ scrollView = scrollView; self. constraint = NO; [scrollView addConstraint: [NSLayoutConstraint constraintWithItem: self attribute: inclurelatedby: inclutoitem: scrollView attribute: inclumultiplier: 1.0f constant: 0]; [scrollView addstraint: [constraint attributes: self attribute: inclurelatedby: inclutoitem: scrollView attribute: inclumultiplier: 1.0f constant: 0]; [scrollView addConstraint: [NSLayoutConstraint constraintWithItem: self attribute: inclurelatedby: optional toItem: scrollView attribute: Invalid multiplier: 1.0f constant: 0]; [scrollView addObserver: self forKeyPath: Unsupported options: Unsupported context: nil]; [self addConstraint: [NSLayoutConstraint constraintWithItem: self attribute: NSLayoutAttributeHeight relatedBy: NSLayoutRelationEqual toItem: nil attribute: NSLayoutAttributeNotAnAttribute multiplier: 1.0f constant: [scrollView contentSize]. height]; // directly set the contentSize of the scrollView when it is bound for the first time. height as panel height}-(void) observeValueForKeyPath :( NSString *) keyPath ofObject :( id) object change :( NSDictionary *) change context :( void *) context {if ([keyPath is1_tostring: KVCUIPanelString_ContentSize]) {[self removeConstraints: self. constraints]; [self addConstraint: [NSLayoutConstraint constraintWithItem: self attribute: inclurelatedby: inclutoitem: nil attribute: inclumultiplier: 1.0f constant: [(UIScrollView *) object contentSize] height] ;}}

Remember to release it when using kvo.

-(void)removeFromSuperview{    [super removeFromSuperview];    if(_scrollView){        [_scrollView removeObserver:self forKeyPath:KVCUIPanelString_ContentSize context:nil];        _scrollView=nil;    }}

The method has been encapsulated, so the following is how to use it. The Code is as follows:

// Initialize UIScrollView * scroll = [[UIScrollView alloc] init]; scroll. backgroundColor = [UIColor blueColor]; scroll. isBindSizeToSuperView = YES; // bind the height and width of UIScrollView to the parent view [self. view addSubview: scroll]; [scroll setContentSize: CGSizeMake (100,100 0)]; // set the contentSize UIStackPanel * _ panel of UIScrollView to [[UIStackPanel alloc] init]; [scroll addSubview: _ panel]; _ panel. backgroundColor = [UIColor yellowColor]; [_ panel bindToScrollView: scroll]; // bind UIStackPanel to UIScrollView UILabel * label = [[UILabel alloc] initWithSize: CGSizeMake (100, 50)]; label. backgroundColor = [UIColor blackColor]; label. textColor = [UIColor whiteColor]; label. font = [UIFont systemFontOfSize: 12]; label. text = @ "Label1"; label. textAlignment = NSTextAlignmentCenter; [_ panel addSubview: label]; label = [[UILabel alloc] initWithSize: CGSizeMake (100, 50)]; label. backgroundColor = [UIColor blackColor]; label. textColor = [UIColor whiteColor]; label. font = [UIFont systemFontOfSize: 12]; label. text = @ "Label2"; label. margin = UIEdgeInsetsMake (10, 0, 0, 0); label. textAlignment = NSTextAlignmentCenter; [_ panel addSubview: label];

Now, the uiscrollview automation solution has been completed.

 

Next, we will introduce how the UIView is docked in the superView. No matter how the height and width of the superview are changed, the position of the UIView is not changed.

The source code of this article will be provided in the next article.

 




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.