私はiOS用のアプリを開発していて、AutoLayout ONでStoryboardを使用しています。私のView Controllerの1つには4つのボタンのセットがあり、特定の状況では最初のボタンを非表示にしたいと思います。
setHidden:TRUE
メソッドを使用すると、UIButtonが非表示になりますが、それでもビュー内のスペースを明らかに消費し、結果は「穴」になり、残りのUIButtonを上に浮かせて埋めることができません。メインビューの。
AndroidではView.GONE
の代わりにView.INVISIBLE
を使用していましたが、iOSではこの動作にこだわっています。解決策は、残りの要素を手動で(はい、プログラム的に)移動することです。
Androidのようにすべてを自動にするために何らかの制約を設定してそれを行うことができると思っていましたが、運がありませんでした。
自動レイアウトをオフにする前に、誰かが私を正しい方向に向けることができますか?
私はIBを使用していますが、プログラマティックなものにも慣れています。
更新:
コンポーネントの高さを0に設定しても役に立ちません。
私は次のようなものを試しました:
UIButton *b;
CGRect frameRect = b.frame;
frameRect.size.height = 0;
b.frame = frameRect;
ビューの高さを0に設定する制約(NSLayoutAttributeHeight)を追加するとうまくいきました:
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.captchaView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:0]];
この質問に対する答えはすべて非効率的です。 Android iOSのsetVisibility:Goneメソッドを同等にする最も良い方法は、StackView
が最初にコンポーネントを選択し、次にエディターで、スタックビューを埋め込み、
新しいスタックビューをIBOutletに接続してから:
非表示:
UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0];
firstView.hidden = YES;
可視性:
UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0];
firstView.hidden = NO;
スタックビューを使用すると、すべての制約が保持されます。
できることは、ビューをスタックビューの下にグループ化することです。次に、特定のビューを非表示にすると、残りのビューが自動的に移動してスペースがいっぱいになります。
Appleスタックビューに関するドキュメント: https://developer.Apple.com/reference/uikit/uistackview
または次のようなオンラインチュートリアル: https://www.appcoda.com/stack-views-intro/
IOSでAndroids.GONE機能を実現するには、UIStackViewを使用します。その後、位置によって子を非表示にします。 ( Appleドキュメント )
Swift 4:
let firstView = cell.rootStackView.arrangedSubviews[0]
firstView.isHidden = true // first view gone
これは表のセルの例です。両方の内部にStack view
およびGONE
のアイテムを取得します。
この質問はかなり古いですが、私が見つけた最も近いものは追加の制約を設定することです(「なくなった」ビューの周りのビューは、行方不明になったらどうするかを知っています)
A which you want to be A
| after setting B to gone |
B C
|
C
bConstraints
にBの上下の制約(または、ビューを水平方向に折りたたむ場合は左右)を追加します。これを行う:bConstraints
を入れます。@IBOutlet var bConstraints: [NSLayoutConstraint]!
ViewController次に、Bを非表示にします
B.hidden = true
NSLayoutConstraint.deactivateConstraints(bConstraints)
再表示する
B.hidden = false
NSLayoutConstraint.activateConstraints(bConstraints)
当然のことながら、各ビューから追加の制約が必要になるため、ビューがますます複雑になります。
https://github.com/tazihosniomar/LayoutManager
それがあなたの役に立つことを願っています。
1)ボタンを垂直に配置する場合は、height
を0に設定する必要があります。水平に配置するボタンの場合は、width
を0に設定するか、両方を0に設定してください。
OR
2)button2
の上にbutton1
を設定するこのアプローチを試すことができます:
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button1 setTitle:@"hello" forState:UIControlStateNormal];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button2 setTitle:@"world" forState:UIControlStateNormal];
[button1 sizeToFit]; [button2 sizeToFit];
[button2 setFrame:CGRectMake(button1.frame.Origin.x, button1.frame.Origin.y, button2.frame.size.width, button2.frame.size.height)];
[self.view addSubview:button1];
[self.view addSubview:button2];
}
私の研究が示しているように、AutoLayoutでさえあなたを助けることはできません。オプションで表示されるコンポーネントの影響を受けるビューを手動で置き換える必要があります(私の場合、すべてのビューはオプションのビューの下部にありますが、オプションのボタンの右側にあるすべてのボタンを処理するようにこれを調整することができます) ):
- (IBAction)toggleOptionalView:(id)sender {
if (!_expanded) {
self.optionalView.frame = CGRectMake(self.optionalView.frame.Origin.x, self.optionalView.frame.Origin.y, self.optionalView.frame.size.width, _optionalHeight);
self.bottomView.frame = CGRectMake(self.bottomView.frame.Origin.x, self.bottomView.frame.Origin.y+_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height);
_expanded = YES;
} else {
self.optionalView.frame = CGRectMake(self.optionalView.frame.Origin.x, self.optionalView.frame.Origin.y, self.optionalView.frame.size.width, 0);
self.bottomView.frame = CGRectMake(self.bottomView.frame.Origin.x, self.bottomView.frame.Origin.y-_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height);
_expanded = NO;
}
}
オプションのコンポーネントの高さ/幅をハードコードしないことをお勧めします。そうしないと、XIB /ストーリーボードを編集するたびにコードが破損します。 viewDidLoadで設定したfloat _optionalHeightフィールドがあるので、常に最新です。
ページ、または少なくともページの特定のセルをクリアして、全体を再定義することもできます。それは高速でうまく動作します。私はコードを書きませんでしたが、私が取り組んでいるこの既存のプロジェクトで見つけました。 ManagementTableSection
およびManagementTableCell
クラスを作成して、すべてを管理します。申し訳ありませんが、より適切に定義されたコードを提供することはできません。
「visible」というカスタムUIView実装に新しいプロパティを追加し、falseに設定するとビューを折りたたむ制約を追加します(リストが水平であるため幅の制約のみを追加しましたが、最良の方法は高さの制約も0)。
var visible:Bool = true{
didSet{
if(visible){
clipsToBounds = false;
removeConstraint(hideConstraint!)
}else{
clipsToBounds = true
addConstraint(hideConstraint!)
}
}
}
ビューのゼロ幅制約を初期化し、フィールドとして追加する必要があります。
private var hideConstraint:NSLayoutConstraint?
func someInitFunction(){
hideConstraint = NSLayoutConstraint(item: self, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 0.0)
...
}
Denizが提供する答えを基に、ここにSwiftの制約を使用したソリューションがあります
例:3つのビュー、A_view B_viewおよびC_viewがこの順序で垂直に並んでいて、Bを「非表示」にして差を調整する場合は、制約を追加します
B_view.removeFromSuperView()
var constr = NSLayoutConstraint(item: C_view,
attribute: NSLayoutAttribute.Top,
relatedBy: NSLayoutRelation.Equal,
toItem: A_view,
attribute: NSLayoutAttribute.Bottom,
multiplier: 1,
constant: 20)
view.addConstraint(constr)
定数は(この場合)C_viewとA_viewの間の垂直方向のスペースの量です。