web-dev-qa-db-ja.com

プログラムでUIScrollViewのAutoLayoutでサブビューを設定する方法は?

私は、プログラムでAutolayoutを使用して、UiScrollviewとUIPagectontrolでアプリを作成しています。

UIViewのサブクラスとしてTKScrollerを作成しました。SomeModeとArrayを使用して初期化しています。

TKScroller.m

-(void)setData{

[self layoutIfNeeded];
CGRect mainFrame=self.frame;


[self layoutIfNeeded];
CGRect mainFrame=self.frame;
UIView *lastview;
NSMutableArray* manualConstraints = [NSMutableArray array];

for (int i=0; i<arrayData.count ; i++)
{
    CGRect frame;
    frame.Origin.x = scrollView.frame.size.width * i;
    frame.Origin.y = 0;
    frame.size = scrollView.frame.size;

    UIView *subview = [UIView new];

    subview.backgroundColor = [self getRandomColor];
    [scrollView addSubview:subview];

    if (i==0)
    {

        NSLayoutConstraint* b1_top = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:5];
        [manualConstraints addObject:b1_top];

        NSLayoutConstraint* b1_left = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeLeading multiplier:1 constant:5];
        [manualConstraints addObject:b1_left];

        NSLayoutConstraint* b1_right = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTrailing multiplier:1 constant:-5];
        [manualConstraints addObject:b1_right];
        NSLayoutConstraint* b1_bottom = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:-10];
        [manualConstraints addObject:b1_bottom];

        [subview layoutIfNeeded];
        [scrollView addConstraints:manualConstraints];
        lastview=subview;
    }
    else{

        NSLayoutConstraint* b1_top = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:5];
        [manualConstraints addObject:b1_top];

        NSLayoutConstraint* b1_left = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:lastview attribute:NSLayoutAttributeLeading multiplier:1 constant:5];
        [manualConstraints addObject:b1_left];

        NSLayoutConstraint* b1_right = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTrailing multiplier:1 constant:-5];
        [manualConstraints addObject:b1_right];
        NSLayoutConstraint* b1_bottom = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:-10];
        [manualConstraints addObject:b1_bottom];

        [subview layoutIfNeeded];
        [scrollView addConstraints:manualConstraints];
        lastview=subview;

    }
}

scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * arrayData.count, mainFrame.size.height/2);

self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = arrayData.count;

 pageControlBeingUsed = NO;
}

-(UIColor *)getRandomColor{
    int r = arc4random() % 255;
    int g = arc4random() % 255;
    int b = arc4random() % 255;
    return [UIColor colorWithRed:(r/255.0) green:(g/255.0) blue:(b/255.0) alpha:1.0];
}

現在、サブビューを取得しています。

しかし、方向を変更すると、正しくない結果が得られます。そのため、scrollviewのサブビューにNSLayoutConstraintを与えるにはどうすればよいですか?

[〜#〜]編集[〜#〜]

NSLayoutConstraintを追加した後、サブビューは表示されません。いくつかの制約がありません。動的に制約を設定する際に修正してください。

ソースコードはこちら、私を助けてください。ありがとうございました。そして文法がおかしい。

11
user2893025

ここにSO答え が自動レイアウトでこれを行う方法を説明しました、彼は完全に説明しました、ここには垂直方向のテキストフィールドがありますが、あなたの場合は水平ビューの制約を設定する必要があります。

代替

制約を設定するのではなく、サブビューのフレームのみを設定し、それをスクロールビューに設定できます。方向に基づいて、スクロールビューのサブビューのフレームを変更できます。

あなたのsetDataメソッドのような、

-(void)setData{

    [self layoutIfNeeded];
    CGRect mainFrame=scrollView.frame;
    CGRect frame;
    for (int i=0; i<arrayData.count ; i++)
    {
        CGRect frame;
        frame.Origin.x = scrollView.frame.size.width * i;
        frame.Origin.y = 0;
        frame.size = scrollView.frame.size;

        frame.Origin=CGPointMake(0, 0);
        UIView *subview = [[UIView alloc]initWithFrame:frame];
        subview.backgroundColor = [self getRandomColor];
        [scrollView addSubview:subview];
    }
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * arrayData.count, mainFrame.size.height/2);
}

NSNotificationCenterを使用すると、デバイスの向きが変更されたときに通知を受け取ることができるため、このセレクターメソッドでsetDataメソッドを呼び出します。

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(setData)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil];

デバイスの向きを変更すると、スクロールビューに新しいビューが追加されるため、setDataメソッドですべてのサブビューを削除する必要があります。フレームを設定する前に、Scrollviewからすべてのサブビューを削除します。

        [scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

オブザーバーをクラスから削除していることを確認してください。

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
6
Toseef Khilji

AutoLayoutでの私の経験では(プログラムでも使用しています)。ビューをUIScrollViewに直接追加しないでください。

UIViewのサブビューとして追加する1つのUIScrollViewと1つだけを実行する必要があります。

これが完了したら、すべてのサブビューをこのUIViewに追加できます。

すべてがここで詳細に説明されています: Apple iOS Technical Note TN2154

10
AncAinu

私は問題が解決したことを知っています。そして、私はこの解決策が私の人々の助けになることを願っていますので、私はそれを投稿しています。

以下のコードは、uiviewcontrollerにscrollviewを追加するためのものです

  self.scrollView = UIScrollView()
    self.scrollView.backgroundColor = UIColor.greenColor()
    self.scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
    self.scrollView.scrollEnabled=true
    self.scrollView.pagingEnabled = true
    self.view.addSubview(self.scrollView)

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["scrollView":self.scrollView]))

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["scrollView":self.scrollView]))

スクロールビューを追加し、このようにサブビュー/画像を追加した後(これは、写真アプリのようにスクロールビューのフルサイズで表示される画像の例です)

var prev:UIImgeView?

        for var index = 0; index < self.images.count; ++index {
            var iview = UIImgeView()
            iview.setTranslatesAutoresizingMaskIntoConstraints(false)
            self.scrollView.addSubview(iview)
            var image = self.images.objectAtIndex(index) as UIImage
            iview.image = image
            if (index == 0){
                self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[iview(==scrollView)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"scrollView":self.scrollView]))
                prev = iview

            }
            else{
                self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[prev][iview(==prev)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"prev":prev!]))
                prev = iview
            }
            self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[iview(==scrollView)]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"scrollView":self.scrollView]))

            if (index == self.images.count-1){
                self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[prev]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["prev":prev!]))

            }

        }
5
sateesh

TKScrollerを中央に固定して向きの変更をサポートする場合は、次のコードをinitに挿入するだけです。

self.autoresizingMask = UIViewAutoresizingFlexibleWidth;

そして、TKScrollerのすべてのサブビューをチェックする必要があるかもしれません。 autosizeが気に入らない場合は、(3つのうちの1つ)を設定できます。

self.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
0
Baoyu