UIStackView에서 프로그래밍 방식으로 보기 추가
UIStackView에서 보기를 프로그래밍 방식으로 추가하려고 합니다.현재 내 코드는:
UIView *view1 = [[UIView alloc]init];
view1.backgroundColor = [UIColor blackColor];
[view1 setFrame:CGRectMake(0, 0, 100, 100)];
UIView *view2 = [[UIView alloc]init];
view2.backgroundColor = [UIColor greenColor];
[view2 setFrame:CGRectMake(0, 100, 100, 100)];
[self.stack1 addArrangedSubview:view1];
[self.stack1 addArrangedSubview:view2];
앱을 배포할 때 화면은 1개뿐이고 검은색으로 되어 있습니다.(view1은 view2에 대한 파라미터도 가져옵니다.)
스택 뷰는 고유한 컨텐츠 크기를 사용하므로 레이아웃 제약 조건을 사용하여 뷰의 치수를 정의합니다.
제약조건을 신속하게 추가하는 간단한 방법이 있습니다(예).
[view1.heightAnchor constraintEqualToConstant:100].active = true;
완전한 코드:
- (void) setup {
//View 1
UIView *view1 = [[UIView alloc] init];
view1.backgroundColor = [UIColor blueColor];
[view1.heightAnchor constraintEqualToConstant:100].active = true;
[view1.widthAnchor constraintEqualToConstant:120].active = true;
//View 2
UIView *view2 = [[UIView alloc] init];
view2.backgroundColor = [UIColor greenColor];
[view2.heightAnchor constraintEqualToConstant:100].active = true;
[view2.widthAnchor constraintEqualToConstant:70].active = true;
//View 3
UIView *view3 = [[UIView alloc] init];
view3.backgroundColor = [UIColor magentaColor];
[view3.heightAnchor constraintEqualToConstant:100].active = true;
[view3.widthAnchor constraintEqualToConstant:180].active = true;
//Stack View
UIStackView *stackView = [[UIStackView alloc] init];
stackView.axis = UILayoutConstraintAxisVertical;
stackView.distribution = UIStackViewDistributionEqualSpacing;
stackView.alignment = UIStackViewAlignmentCenter;
stackView.spacing = 30;
[stackView addArrangedSubview:view1];
[stackView addArrangedSubview:view2];
[stackView addArrangedSubview:view3];
stackView.translatesAutoresizingMaskIntoConstraints = false;
[self.view addSubview:stackView];
//Layout for Stack View
[stackView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = true;
[stackView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = true;
}
주의: 이것은 iOS 9에서 테스트되었습니다.
Swift 5.0
//Image View
let imageView = UIImageView()
imageView.backgroundColor = UIColor.blue
imageView.heightAnchor.constraint(equalToConstant: 120.0).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 120.0).isActive = true
imageView.image = UIImage(named: "buttonFollowCheckGreen")
//Text Label
let textLabel = UILabel()
textLabel.backgroundColor = UIColor.yellow
textLabel.widthAnchor.constraint(equalToConstant: self.view.frame.width).isActive = true
textLabel.heightAnchor.constraint(equalToConstant: 20.0).isActive = true
textLabel.text = "Hi World"
textLabel.textAlignment = .center
//Stack View
let stackView = UIStackView()
stackView.axis = NSLayoutConstraint.Axis.vertical
stackView.distribution = UIStackView.Distribution.equalSpacing
stackView.alignment = UIStackView.Alignment.center
stackView.spacing = 16.0
stackView.addArrangedSubview(imageView)
stackView.addArrangedSubview(textLabel)
stackView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(stackView)
//Constraints
stackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
@user1046037의 답변에 근거합니다.
Swift 4.2의 경우
let redView = UIView()
redView.backgroundColor = .red
let blueView = UIView()
blueView.backgroundColor = .blue
let stackView = UIStackView(arrangedSubviews: [redView, blueView])
stackView.axis = .vertical
stackView.distribution = .fillEqually
view.addSubview(stackView)
// stackView.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
// autolayout constraint
stackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: view.topAnchor),
stackView.leftAnchor.constraint(equalTo: view.leftAnchor),
stackView.rightAnchor.constraint(equalTo: view.rightAnchor),
stackView.heightAnchor.constraint(equalToConstant: 200)
])
UIStackView
는 내부적으로 구속조건을 사용하여 정렬된 서브뷰를 배치합니다.생성되는 제약조건은 스택뷰 자체의 설정 방법에 따라 달라집니다.기본적으로 스택 뷰는 정렬된 하위 뷰를 수평선으로 배치하는 구속조건을 생성하여 선행 및 후행 뷰를 자체 선행 및 후행 에지에 고정합니다.따라서 코드에서는 다음과 같은 레이아웃이 생성됩니다.
|[view1][view2]|
각 서브뷰에 할당되는 공간은 서브뷰 고유의 콘텐츠 크기, 압축 저항성 및 콘텐츠 포옹 우선순위 등 여러 요소에 의해 결정됩니다." " " 입니다.UIView
인스턴스는 고유한 콘텐츠 크기를 정의하지 않습니다.클래스에서 입니다.UILabel
★★★★★★★★★★★★★★★★★」UIButton
콘텐츠 가 있기 UIView
인스턴스는 동일하며, 어느 뷰도 고유의 콘텐츠 크기를 제공하지 않으므로 레이아웃 엔진은 각 뷰에 할당해야 할 크기를 최대한 추측해야 합니다.이 경우 첫 번째 뷰는 사용 가능한 공간의 100%를 할당하고 두 번째 뷰에는 아무것도 할당하지 않습니다.
하여 「」를 사용했을 UILabel
인스턴스 대신 더 나은 결과를 얻을 수 있습니다.
UILabel *label1 = [UILabel new];
label1.text = @"Label 1";
label1.backgroundColor = [UIColor blueColor];
UILabel *label2 = [UILabel new];
label2.text = @"Label 2";
label2.backgroundColor = [UIColor greenColor];
[self.stack1 addArrangedSubview:label1];
[self.stack1 addArrangedSubview:label2];
제약조건을 직접 상세하게 작성할 필요는 없습니다.이것은, 사용의 주된 장점입니다.UIStackView
세부사항을 - -- - 흔흔 、 흔흔 ( 흔 - ) 。
배포 유형을 설정해야 합니다.코드에 다음 내용을 추가합니다.
self.stack1.distribution = UIStackViewDistributionFillEqually;
또는, 인터페이스 빌더로 직접 전달을 설정할 수도 있습니다.예를 들어 다음과 같습니다.
그것이 도움이 되기를 바란다;) 라피노.
다음 두 줄에 따라 문제가 해결되었습니다.
view.heightAnchor.constraintEqualToConstant(50).active = true;
view.widthAnchor.constraintEqualToConstant(350).active = true;
빠른 버전 -
var DynamicView=UIView(frame: CGRectMake(100, 200, 100, 100))
DynamicView.backgroundColor=UIColor.greenColor()
DynamicView.layer.cornerRadius=25
DynamicView.layer.borderWidth=2
self.view.addSubview(DynamicView)
DynamicView.heightAnchor.constraintEqualToConstant(50).active = true;
DynamicView.widthAnchor.constraintEqualToConstant(350).active = true;
var DynamicView2=UIView(frame: CGRectMake(100, 310, 100, 100))
DynamicView2.backgroundColor=UIColor.greenColor()
DynamicView2.layer.cornerRadius=25
DynamicView2.layer.borderWidth=2
self.view.addSubview(DynamicView2)
DynamicView2.heightAnchor.constraintEqualToConstant(50).active = true;
DynamicView2.widthAnchor.constraintEqualToConstant(350).active = true;
var DynamicView3:UIView=UIView(frame: CGRectMake(10, 420, 355, 100))
DynamicView3.backgroundColor=UIColor.greenColor()
DynamicView3.layer.cornerRadius=25
DynamicView3.layer.borderWidth=2
self.view.addSubview(DynamicView3)
let yourLabel:UILabel = UILabel(frame: CGRectMake(110, 10, 200, 20))
yourLabel.textColor = UIColor.whiteColor()
//yourLabel.backgroundColor = UIColor.blackColor()
yourLabel.text = "mylabel text"
DynamicView3.addSubview(yourLabel)
DynamicView3.heightAnchor.constraintEqualToConstant(50).active = true;
DynamicView3.widthAnchor.constraintEqualToConstant(350).active = true;
let stackView = UIStackView()
stackView.axis = UILayoutConstraintAxis.Vertical
stackView.distribution = UIStackViewDistribution.EqualSpacing
stackView.alignment = UIStackViewAlignment.Center
stackView.spacing = 30
stackView.addArrangedSubview(DynamicView)
stackView.addArrangedSubview(DynamicView2)
stackView.addArrangedSubview(DynamicView3)
stackView.translatesAutoresizingMaskIntoConstraints = false;
self.view.addSubview(stackView)
//Constraints
stackView.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor).active = true
stackView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor).active = true
스택 뷰 내에서 뷰를 숨기려고 할 때 허용되는 응답의 경우 제약조건이 올바르게 작동하지 않습니다.
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x618000086e50 UIView:0x7fc11c4051c0.height == 120 (active)>",
"<NSLayoutConstraint:0x610000084fb0 'UISV-hiding' UIView:0x7fc11c4051c0.height == 0 (active)>"
)
그 이유는, 이 파일을 숨김으로써view
stackView
높이를 0으로 설정하여 애니메이션을 만듭니다.
솔루션 제약 조건 변경priority
하와같같 같같같다다
import UIKit
class ViewController: UIViewController {
let stackView = UIStackView()
let a = UIView()
let b = UIView()
override func viewDidLoad() {
super.viewDidLoad()
a.backgroundColor = UIColor.red
a.widthAnchor.constraint(equalToConstant: 200).isActive = true
let aHeight = a.heightAnchor.constraint(equalToConstant: 120)
aHeight.isActive = true
aHeight.priority = 999
let bHeight = b.heightAnchor.constraint(equalToConstant: 120)
bHeight.isActive = true
bHeight.priority = 999
b.backgroundColor = UIColor.green
b.widthAnchor.constraint(equalToConstant: 200).isActive = true
view.addSubview(stackView)
stackView.backgroundColor = UIColor.blue
stackView.addArrangedSubview(a)
stackView.addArrangedSubview(b)
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.translatesAutoresizingMaskIntoConstraints = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Just add a button in xib file or storyboard and add connect this action.
@IBAction func test(_ sender: Any) {
a.isHidden = !a.isHidden
}
}
//Image View
let imageView = UIImageView()
imageView.backgroundColor = UIColor.blueColor()
imageView.heightAnchor.constraintEqualToConstant(120.0).active = true
imageView.widthAnchor.constraintEqualToConstant(120.0).active = true
imageView.image = UIImage(named: "buttonFollowCheckGreen")
//Text Label
let textLabel = UILabel()
textLabel.backgroundColor = UIColor.greenColor()
textLabel.widthAnchor.constraintEqualToConstant(self.view.frame.width).active = true
textLabel.heightAnchor.constraintEqualToConstant(20.0).active = true
textLabel.text = "Hi World"
textLabel.textAlignment = .Center
//Third View
let thirdView = UIImageView()
thirdView.backgroundColor = UIColor.magentaColor()
thirdView.heightAnchor.constraintEqualToConstant(120.0).active = true
thirdView.widthAnchor.constraintEqualToConstant(120.0).active = true
thirdView.image = UIImage(named: "buttonFollowMagenta")
//Stack View
let stackView = UIStackView()
stackView.axis = UILayoutConstraintAxis.Vertical
stackView.distribution = UIStackViewDistribution.EqualSpacing
stackView.alignment = UIStackViewAlignment.Center
stackView.spacing = 16.0
stackView.addArrangedSubview(imageView)
stackView.addArrangedSubview(textLabel)
stackView.addArrangedSubview(thirdView)
stackView.translatesAutoresizingMaskIntoConstraints = false;
self.view.addSubview(stackView)
//Constraints
stackView.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor).active = true
stackView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor).active = true
@Oleg Popov의 답변보다 개선되었습니다.
Swift 5 버전의 Oleg Popov 답변은 사용자 1046037의 답변을 기반으로 합니다.
//Image View
let imageView = UIImageView()
imageView.backgroundColor = UIColor.blue
imageView.heightAnchor.constraint(equalToConstant: 120.0).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 120.0).isActive = true
imageView.image = UIImage(named: "buttonFollowCheckGreen")
//Text Label
let textLabel = UILabel()
textLabel.backgroundColor = UIColor.yellow
textLabel.widthAnchor.constraint(equalToConstant: self.view.frame.width).isActive = true
textLabel.heightAnchor.constraint(equalToConstant: 20.0).isActive = true
textLabel.text = "Hi World"
textLabel.textAlignment = .center
//Stack View
let stackView = UIStackView()
stackView.axis = NSLayoutConstraint.Axis.vertical
stackView.distribution = UIStackView.Distribution.equalSpacing
stackView.alignment = UIStackView.Alignment.center
stackView.spacing = 16.0
stackView.addArrangedSubview(imageView)
stackView.addArrangedSubview(textLabel)
stackView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(stackView)
//Constraints
stackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
내 경우, 내가 예상한 것은 내가 이 줄을 놓치고 있었다는 것이다.
stackView.translatesAutoresizingMaskIntoConstraints = false;
그 후 정렬된 서브뷰에 제약을 가할 필요가 전혀 없습니다.스택뷰가 그 처리를 하고 있습니다.
가 UIView
를 추가할 때는 할 수 .UIView
은 '어디서'에 수 있는 부분이에요.UIStackView
extension UIStackView {
func addArrangedSubviews(_ subviews: [UIView]) {
subviews.forEach{ self.addArrangedSubview($0) }
}
}
특정 위치에 UIView를 추가하려면 다음을 사용하십시오.
yourStackView.insertArrangedSubview(yourView, at: index)
나는 방금 아주 비슷한 문제를 발견했다.스택 뷰의 치수는 앞에서 설명한 바와 같이 정렬된 서브뷰의 고유한 콘텐츠크기에 따라 달라집니다.다음은 Swift 2.x의 솔루션과 다음 뷰 구조입니다.
표시 - UIView
Custom View - Custom View :UIView
stackView - USTackView
정렬된 서브뷰 - 커스텀 UIView 서브클래스
//: [Previous](@previous)
import Foundation
import UIKit
import XCPlayground
/**Container for stack view*/
class CustomView:UIView {
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init(){
super.init(frame: CGRectZero)
}
}
/**Custom Subclass*/
class CustomDrawing:UIView{
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
func setup(){
// self.backgroundColor = UIColor.clearColor()
print("setup \(frame)")
}
override func drawRect(rect: CGRect) {
let ctx = UIGraphicsGetCurrentContext()
CGContextMoveToPoint(ctx, 0, 0)
CGContextAddLineToPoint(ctx, CGRectGetWidth(bounds), CGRectGetHeight(bounds))
CGContextStrokePath(ctx)
print("DrawRect")
}
}
//: [Next](@next)
let stackView = UIStackView()
stackView.distribution = .FillProportionally
stackView.alignment = .Center
stackView.axis = .Horizontal
stackView.spacing = 10
//container view
let view = UIView(frame: CGRectMake(0,0,320,640))
view.backgroundColor = UIColor.darkGrayColor()
//now custom view
let customView = CustomView()
view.addSubview(customView)
customView.translatesAutoresizingMaskIntoConstraints = false
customView.widthAnchor.constraintEqualToConstant(220).active = true
customView.heightAnchor.constraintEqualToConstant(60).active = true
customView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor).active = true
customView.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor).active = true
customView.backgroundColor = UIColor.lightGrayColor()
//add a stack view
customView.addSubview(stackView)
stackView.centerXAnchor.constraintEqualToAnchor(customView.centerXAnchor).active = true
stackView.centerYAnchor.constraintEqualToAnchor(customView.centerYAnchor).active = true
stackView.translatesAutoresizingMaskIntoConstraints = false
let c1 = CustomDrawing()
c1.translatesAutoresizingMaskIntoConstraints = false
c1.backgroundColor = UIColor.redColor()
c1.widthAnchor.constraintEqualToConstant(30).active = true
c1.heightAnchor.constraintEqualToConstant(30).active = true
let c2 = CustomDrawing()
c2.translatesAutoresizingMaskIntoConstraints = false
c2.backgroundColor = UIColor.blueColor()
c2.widthAnchor.constraintEqualToConstant(30).active = true
c2.heightAnchor.constraintEqualToConstant(30).active = true
stackView.addArrangedSubview(c1)
stackView.addArrangedSubview(c2)
XCPlaygroundPage.currentPage.liveView = view
하는 것이 , 을 처리하는 할 수 ..intrinsicContentSize
UIView
더 심플한 방법으로 수업할 수 있습니다.이 솔루션에서는, 「intrinsicWidth」및 「intrinsicHeight」뷰를 서포트하기 위해서, Interface Builder도 약간 개선됩니다.귀하는 UIView를 확장하고 이러한 속성을 IB의 모든 UIView에서 사용할 수 있도록 할 수 있지만, 클리너는 하위 클래스로 이동합니다.
// IntrinsicView.h
@import UIKit
IB_DESIGNABLE
@interface IntrinsicView : UIView
-(instancetype)initWithFrame:(CGRect)rect;
@property IBInspectable CGSize intrinsic;
@end
// IntrinsicView.m
#import "IntrinsicView.h"
@implementation IntrinsicView {
CGSize _intrinsic;
}
- (instancetype)initWithFrame:(CGRect)frame {
_intrinsic = frame.size;
if ( !(self = [super initWithFrame:frame]) ) return nil;
// your stuff here..
return self;
}
-(CGSize)intrinsicContentSize {
return _intrinsic;
}
-(void)prepareForInterfaceBuilder {
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, _intrinsic.width,_intrinsic.height);
}
@end
, IntrentialView와 IntrentialView를 할당할 수 .self.frame.size
라고 생각되다intrinsicContentSize
, 완전히 UIStackViews
#import "IntrinsicView.h"
- (void)viewDidLoad {
[super viewDidLoad];
UIStackView *column = [[UIStackView alloc] initWithFrame:self.view.frame];
column.spacing = 2;
column.alignment = UIStackViewAlignmentFill;
column.axis = UILayoutConstraintAxisVertical; //Up-Down
column.distribution = UIStackViewDistributionFillEqually;
for (int row=0; row<5; row++) {
//..frame:(CGRect) defines here proportions and
//relation to axis of StackView
IntrinsicView *intrinsicView = [[IntrinsicView alloc] initWithFrame:CGRectMake(0, 0, 30.0, 30.0)];
[column addArrangedSubview:intrinsicView];
}
[self.view addSubview:column];
}
UIStackView를 통해 열광할 수 있게 되었습니다.
또는 신속한 + 인코딩, 디코딩, IB 지원, Objective-C 지원
@IBDesignable @objc class IntrinsicView : UIView {
@IBInspectable var intrinsic : CGSize
@objc override init(frame: CGRect) {
intrinsic = frame.size
super.init(frame: frame)
}
required init?(coder: NSCoder) {
intrinsic = coder.decodeCGSize(forKey: "intrinsic")
super.init(coder: coder)
}
override func encode(with coder: NSCoder) {
coder.encode(intrinsic, forKey: "intrinsic")
super.encode(with: coder)
}
override var intrinsicContentSize: CGSize {
return intrinsic
}
override func prepareForInterfaceBuilder() {
frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: intrinsic.width, height: intrinsic.height)
}
}
높이 제한을 설정하는 것은 권장되지 않습니다.만약 할 수 있다면, 절대, 절대, 절대 높이를 설정하지 마세요!UIStackView 내 뷰의 모든 구속조건을 체크하고 하단, 상단, 선행 및 후행의 구속조건이 있는지 확인해야 합니다.누군가 나에게 말했다: 그것은 벽을 밀고 있는 사람 같다.사면을 밀지 않으면 한쪽 벽이 무너질 거예요.
func configureHorizontalView(){
containerView.addSubview(horizontalStackView)
_ = horizontalStackView.anchor(top: secondCurrencyTextField.bottomAnchor,
left: containerView.leftAnchor,
bottom: nil,
right: containerView.rightAnchor,
topConstant: 40,
leftConstant: 30,
bottomConstant: 0,
rightConstant: 30,
widthConstant: 0,
heightConstant: 65)
}
func configureFirstDropDownlabel(){
//add a view to stackView with addArrangedSubview()
horizontalStackView.addArrangedSubview(firstDropDownlabel)
_ = firstDropDownlabel.anchor(top: horizontalStackView.bottomAnchor,
left: horizontalStackView.leftAnchor,
bottom: nil, right: nil,
topConstant: 40,
leftConstant: 30,
bottomConstant: 0,
rightConstant: 0,
widthConstant: 0,
heightConstant: 0)
firstDropDownlabel.widthAnchor.constraint(equalToConstant: 130).isActive = true
firstDropDownlabel.heightAnchor.constraint(equalToConstant: 65).isActive = true
}
아래 코드 시도:
UIView *view1 = [[UIView alloc]init];
view1.backgroundColor = [UIColor blackColor];
[view1 setFrame:CGRectMake(0, 0, 50, 50)];
UIView *view2 = [[UIView alloc]init];
view2.backgroundColor = [UIColor greenColor];
[view2 setFrame:CGRectMake(0, 100, 100, 100)];
NSArray *subView = [NSArray arrayWithObjects:view1,view2, nil];
[self.stack1 initWithArrangedSubviews:subView];
언급URL : https://stackoverflow.com/questions/30728062/add-views-in-uistackview-programmatically
'programing' 카테고리의 다른 글
C#에서 문자를 반복하는 가장 좋은 방법 (0) | 2023.04.16 |
---|---|
MVVM 및 VM 컬렉션 (0) | 2023.04.16 |
각 시트를 워크북에 저장하여 CSV 파일을 구분합니다. (0) | 2023.04.16 |
stdout의 COPY를 bash 스크립트 자체에서 로그 파일로 리다이렉트 (0) | 2023.04.16 |
"TypeError: method()는 1개의 positional 인수를 사용하지만 2개의 positional 인수가 지정되었습니다." 그러나 1개만 통과했습니다. (0) | 2023.04.16 |