8

私はここでひどく明白な何かを見逃しているに違いありませんが、これはDAYSの間私を苛立たせている問題でした。

xcode 4.5のiOSプロジェクトでは、XIBにいくつかのラベルがありUIScrollViewますUIView。各ラベルはビューと同じ幅で、それぞれが次のラベルより約20ピクセル上にあります。場合によっては、ラベルの1つに情報がないため、ラベルが非表示に設定され、その下のラベルが上に移動して空白スペースを占めることになります。

問題は、ビューで自動レイアウトが「オフ」にチェックされている場合、ラベルはUIScrollViewスクロールしなくなりますが、正確に上に移動することです。オンの場合、ラベルは何があってもまったく移動しません。

コードは次のとおりです...基本的には、クイック関数を使用して、各ラベルを非表示のラベルの高さだけ上に移動します。

[self moveObjectBy: self.festNameLabel moveByY:-(yearsLabel.frame.size.height-2)];


// this just quickly moves a label. 
- (void)moveObjectBy:(UIView *)lbl moveByY:(int)byHeight {
    CGRect newFrame = lbl.frame;
    NSLog(@"%f, %d", newFrame.origin.y, byHeight);
    newFrame.origin.y += byHeight; //yearsLabel.frame.size.height;
    lbl.frame = newFrame;
}

実行すると、NSLogYが移動したことが表示されますが、画面上では移動しません。垂直方向のスペース制約に関係していると確信していますが、制約を削除したり、ビューの上部からスペース以外に変更したりすることはできません。私が言ったように、私は何かが欠けていると確信しています、しかし私は私がすることを知っているすべてを使い果たしました...

4

3 に答える 3

14

非表示になっている可能性のあるラベルが 1 つしかない場合は、その下にあるラベルを次のように上に移動できます。

 -(void)contract {
    self.label2.hidden = YES;
    self.con2To1.constant = -34;
}

上部のラベルにはスクロール ビューの上部に対する制約があり、他のすべてのラベルには、その上下のラベルに対して 20 ポイントの垂直距離の制約があります。この例では、label2 を非表示にしています。ラベルの高さはすべて 34 ポイントであるため、制約定数を 20 から -34 に変更すると、非表示になったラベルがその上のラベルの上に移動します。

非表示にできる複数のラベルでこのメソッドを使用するには、非表示にする各ラベルへのアウトレットと、上のラベルへの制約へのアウトレットが必要です。実際には、制約への出口がなくても実行できますが、それがそれほど堅牢であるかどうかはわかりません (間違った制約を選択する可能性があります)。制約をループして、特定のラベルが付いているものを見つけ、そのラベルの一番上にあるものを見つけることで、同じことを行うことができました。

-(void)hideLabel:(UILabel *) label {
    label.hidden = YES;
    for (NSLayoutConstraint *con in self.scroller.constraints) {
        if (con.firstItem == label  && con.firstAttribute == NSLayoutAttributeTop) {
            con.constant = -34;
        }
    }
}

必要に応じて、同じメソッドを変更してアニメーションを使用することもできます。次のスニペットは、非表示にするラベルをフェードアウトさせ、下にあるすべてのラベルを上に移動するアニメーションを表示します。

 -(void)hideLabel:(UILabel *) label {
    for (NSLayoutConstraint *con in self.scroller.constraints) {
        if (con.firstItem == label  && con.firstAttribute == NSLayoutAttributeTop) {
            con.constant = -34;
            [UIView animateWithDuration:.5 animations:^{
                label.alpha = 0;
                [self.scroller layoutIfNeeded];
            }];
        }
    }
}
于 2012-12-24T23:53:57.907 に答える
5

自動レイアウトを使用すると、サブビューにフレームを設定できません。せいぜい、次のレイアウト パスが発生するまで一時的に機能します。その時点で、制約によって定義されたレイアウトが再確立されます。

ビューに適用されている制約を変更する必要があります。あなたの場合、各ラベルに特定のピンと高さの制約を設定することは賢明です。次に、これらの各制約へのアウトレットを作成できます。高さゼロのラベルの場合は、関連する制約の定数をゼロに設定します。下のラベルが上に移動します。

はがすラベルによっては、2 倍の幅の隙間が残る場合があります。間隔の制約を変更してこれを削除するか、間隔の制約を完全に削除して、各ラベルの高さを少し高くするだけで、ラベルのコンテンツが垂直方向に中央揃えになります。

主なメッセージは、フレームを設定しないことです。代わりに、制約を変更、追加、および/または削除します。

于 2012-12-24T21:02:15.780 に答える
0

迅速に実行したい場合:

for item in self.view.constraints
{
    if item.firstItem .isKindOfClass(UITextField)
    {
        let newField = item.firstItem as! UITextField
        if newField == answerTextField && item.firstAttribute == NSLayoutAttribute.Top
        {
            item.constant = answerFrame.origin.y
            self.view .layoutIfNeeded()
        }
    }
    if item.firstItem .isKindOfClass(UIButton)
    {
        let newField = item.firstItem as! UIButton
        if newField == submitButton && item.firstAttribute == NSLayoutAttribute.Top
        {
            item.constant = submitFrame.origin.y
            self.view .layoutIfNeeded()
        }
    }
}
于 2016-04-28T10:53:02.833 に答える