簡體   English   中英

UIScrollview添加帶有for循環的子視圖水平純自動布局

[英]UIScrollview add subview horizontally pure autolayout with for loop

我有以下UIView層次結構:

-UIView
 -UIScrollView

我對UIScrollview與其超級視圖的關系的約束非常簡單:

@"H:|-%f-[%@]-%f-|"

@"V:|-%f-[%@]-%f-|"

他們正在按預期方式工作。

我試圖將UIImageView添加為scrollview Horizo​​ntal的子視圖。 因此,我的視圖層次結構將變為:

-UIView
 -UIScrollView
  -UIImageView

我正在使用for循環在UIScrollView以編程方式將UIImageView添加為子視圖。

for循環中,如何實現:

[SuperView] -10- [scrollview] -10- [UIImageView] -10- [UIImageView] -10- [UIScrollView] -10- [SuperView]

有問題的部分是大膽的部分。 我試過的

for(int i=1;i<3;i++)
        {
            UIImageView *image = [[UIImageView alloc] init];
            [image setImage:[UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",i]]];
            image.translatesAutoresizingMaskIntoConstraints = NO;
            [_scrollView addSubview:image];

            UIView *superView = _scrollView;



            NSDictionary * views = NSDictionaryOfVariableBindings(superView, image);

            NSString *formate = [NSString stringWithFormat:@"H:|-%f-[%@]-%f-|", scrollViewLeftMarginFromParent, @"image", scrollViewRightMarginFromParent];

            NSArray * WIDTH_CONSTRAINT = [NSLayoutConstraint constraintsWithVisualFormat:formate options:0 metrics:nil views:views];

            formate = [NSString stringWithFormat:@"V:|-%f-[%@]-%f-|", scrollViewTopMarginFromParent, @"image", scrollViewBottomMarginFromParent];

            NSArray * HEIGHT_CONSTRAINT = [NSLayoutConstraint constraintsWithVisualFormat:formate options:0 metrics:nil views:views];
            [superView addConstraints:WIDTH_CONSTRAINT];
            [superView addConstraints:HEIGHT_CONSTRAINT];
        }

我能想到的方法:

    LeftSide:
    [scrollview]-10-[UIImageView]
    Right side:
    [UIImageView]-10-[scrollview]
    in between:
    [UIImageView]-10-[UIImageView]

如果這是正確的方法,那么如何在for循環中實現這一點。

如果不是,那么最好的方法是什么。

實際上,這很簡單。 您的方法是正確的,您所需要的只是將其轉換為代碼的方式。 我將盡力為您簡化這一過程。 我假設UIImageView的寬度和高度為100。您可以根據需要進行更改

-(void)setUI
{
    lastView = nil;   //Declare a UIImageView* as instance var.
    arrayCount = [array count]; //In your case a static count of 3

    for(NSInteger index =0; index < arrayCount; index++)
    {
        UIImageView *view = [[UIImageView alloc] init];
        [self.mainScroll addSubview:view];

        [view setTranslatesAutoresizingMaskIntoConstraints:NO];

        [self.mainScroll addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[view(100)]-20-|" options:0 metrics:nil views:@{@"view":view}]];

        //--> If view is first then pin the leading edge to main ScrollView otherwise to the last View.
        if(lastView == nil && index == 0) {
            [self.mainScroll addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[view(100)]" options:0 metrics:nil views:@{@"view":view}]];
        }
        else {
            [self.mainScroll addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[lastView]-10-[view(100)]" options:0 metrics:nil views:@{@"lastView":lastView, @"view":view}]];
        }
        //--> If View is last then pin the trailing edge to mainScrollView trailing edge.
        if(index == arrayCount-1) {
            [self.mainScroll addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view]-10-|" options:0 metrics:nil views:@{@"view":view}]];
        }
        //--> Assign the current View as last view to keep the reference for next View.
        lastView = view;
    }
}

我遇到過類似的情況,其中滾動視圖及其內容視圖是從IB創建的,但是子視圖是通過編程添加的。 編寫子視圖的約束使View控制器腫。 同樣,for循環得到了很多if和else,因此我編寫了一個UIView子類來處理這種情況。

在IB中為您的Content View更改類類型,獲取它的引用,通過直接設置屬性stackViewItems或方法-(void)insertStackItem:-(void)insertStackItem:atIndex:添加子視圖-(void)insertStackItem:atIndex:

#import "IEScrollContentView.h"

@interface IEScrollContentView()
{
    NSMutableArray * _stackViewItems;
}

@property (nonatomic,strong) NSLayoutConstraint * topConstraint;
@property (nonatomic,strong) NSLayoutConstraint * bottomConstraint;

@end

@implementation IEScrollContentView

@synthesize stackViewItems = _stackViewItems;

//-----------------------------------------------------------------//
#pragma mark - Init Methods
//-----------------------------------------------------------------//

-(instancetype)initWithCoder:(NSCoder *)aDecoder {
    if(self = [super initWithCoder:aDecoder])
        _stackViewItems = [NSMutableArray new];
    return self;
}

-(instancetype)initWithFrame:(CGRect)frame {
    if(self = [super initWithFrame:frame])
        _stackViewItems = [NSMutableArray new];
    return self;
}

//-----------------------------------------------------------------//
#pragma mark - Public Methods
//-----------------------------------------------------------------//

-(void)setStackViewItems:(NSArray *)stackViewItems {
    if(!_stackViewItems)
        _stackViewItems = [NSMutableArray new];

    for (UIView * view in stackViewItems) {
        [self insertStackItem:view];
    }
}

-(void)insertStackItem:(UIView *)stackItem
{
    [self insertStackItem:stackItem atIndex:_stackViewItems.count];
}

-(void)insertStackItem:(UIView *)stackItem atIndex:(NSUInteger)index
{
    if(!stackItem || index > _stackViewItems.count)return;

    if(index == 0)
        [self addView:stackItem
            belowView:self
            aboveView:_stackViewItems.count>0?_stackViewItems.firstObject:self];

    else if(index==_stackViewItems.count)
        [self addView:stackItem
            belowView:_stackViewItems[index-1]
            aboveView:self];
    else
        [self addView:stackItem
            belowView:_stackViewItems[index-1]
            aboveView:_stackViewItems[index]];
}

//-----------------------------------------------------------------//
#pragma mark - Constraining Views
//-----------------------------------------------------------------//

-(void)addView:(UIView *)view belowView:(UIView *)viewAbove aboveView:(UIView *)viewBelow {

    view.translatesAutoresizingMaskIntoConstraints = NO;
    [self addSubview:view];

    NSArray * defaultConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[view]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)];
    NSLayoutConstraint * upperConstraint,* lowerConstraint;

    if(viewAbove==self) {
        [self removeConstraint:_topConstraint];
        upperConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[view]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)].firstObject;
        _topConstraint = upperConstraint;
    }
    else
        upperConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[viewAbove]-0-[view]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view,viewAbove)].firstObject;

    if(viewBelow==self) {
        [self removeConstraint:_bottomConstraint];
        lowerConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[view]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)].firstObject;
        _bottomConstraint = lowerConstraint;
    }
    else
        lowerConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[view]-0-[viewBelow]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view,viewBelow)].firstObject;

    [self addConstraints:defaultConstraints];
    [self addConstraints:@[upperConstraint,lowerConstraint]];

    [_stackViewItems addObject:view];
}

@end

我已經在這里上傳了文件

IEScrollContentView.h IEScrollContentView.hm

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM