Programming

UIStackView의 배경색을 변경하는 방법은 무엇입니까?

procodes 2020. 6. 30. 21:47
반응형

UIStackView의 배경색을 변경하는 방법은 무엇입니까?


UIStackView스토리 보드 검사기에서 배경을 투명에서 흰색 으로 변경하려고 시도 했지만 시뮬레이션 할 때 스택보기의 배경색은 여전히 ​​맑은 색입니다.
의 배경색을 어떻게 바꿀 수 UIStackView있습니까?


이 작업을 수행 할 수 없습니다. UIStackView그리기가 아닌보기이므로 drawRect()호출되지 않으며 배경색이 무시됩니다. 필사적으로 배경색을 원하는 경우 스택보기를 다른 것으로 배치하고 UIView해당보기에 배경색을 지정하십시오.

여기 에서 참조하십시오 .

편집하다:

여기에UIStackView 언급 된 것처럼 또는 아래의 답변 에서 subView를 추가 하고 색상을 지정할 수 있습니다. 이에 대해서는 아래 확인하십시오 .extension

extension UIStackView {
    func addBackground(color: UIColor) {
        let subView = UIView(frame: bounds)
        subView.backgroundColor = color
        subView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        insertSubview(subView, at: 0)
    }
}

그리고 당신은 그것을 다음과 같이 사용할 수 있습니다 :

stackView.addBackground(color: .red)

나는 이렇게한다 :

@IBDesignable
class StackView: UIStackView {
   @IBInspectable private var color: UIColor?
    override var backgroundColor: UIColor? {
        get { return color }
        set {
            color = newValue
            self.setNeedsLayout() // EDIT 2017-02-03 thank you @BruceLiu
        }
    }

    private lazy var backgroundLayer: CAShapeLayer = {
        let layer = CAShapeLayer()
        self.layer.insertSublayer(layer, at: 0)
        return layer
    }()
    override func layoutSubviews() {
        super.layoutSubviews()
        backgroundLayer.path = UIBezierPath(rect: self.bounds).cgPath
        backgroundLayer.fillColor = self.backgroundColor?.cgColor
    }
}

매력처럼 작동


UIStackView렌더링이 아닌 요소이므로 화면에 그려지지 않습니다. 이것은 변화가 backgroundColor본질적으로 아무 것도하지 않음을 의미합니다 . 배경색을 변경하려면 UIView아래와 같이 a를 서브 뷰 (정렬되지 않은)로 추가하십시오 .

extension UIStackView {

    func addBackground(color: UIColor) {
        let subview = UIView(frame: bounds)
        subview.backgroundColor = color
        subview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        insertSubview(subview, at: 0)
    }

}

어쩌면 가장 쉬운, 더 읽기 덜 해키 방법은을 포함하는 것 UIStackViewUIView보기 및 설정 배경 색상.

그리고 그 두 뷰 사이에 자동 레이아웃 제약 조건을 올바르게 구성하는 것을 잊지 마십시오 ... ;-)


TL; DR :이를 수행하는 공식적인 방법은 addSubview:메소드를 사용하여 빈보기를 스택보기에 추가하고 대신 추가 된보기 배경을 설정하는 것입니다.

설명 : UIStackView는 레이아웃이 아닌 특수 UIView 서브 클래스입니다. 너무 많은 속성이 평소처럼 작동하지 않습니다. UIStackView는 배열 된 서브 뷰 만 레이아웃하므로, addSubview:메소드를 사용 하여 UIView를 추가 하고 제한 조건 및 배경색을 설정 하기 만하면 됩니다. 이것은 WWDC 세션에서 인용 하고 싶은 것을 달성하는 공식적인 방법입니다


Pitiphong은 정확하며 배경색으로 스택 뷰를 얻으려면 다음과 같이하십시오.

  let bg = UIView(frame: stackView.bounds)
  bg.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  bg.backgroundColor = UIColor.red

  stackView.insertSubview(bg, at: 0)

그러면 내용이 빨간색 배경에 배치되는 스택 뷰가 제공됩니다.

내용이 가장자리와 맞지 않도록 스택 뷰에 패딩을 추가하려면 코드 또는 스토리 보드에 다음을 추가하십시오 ...

  stackView.isLayoutMarginsRelativeArrangement = true
  stackView.layoutMargins = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)

이것은 Swift 3 및 iOS 10에서 작동합니다.

let stackView = UIStackView()
let subView = UIView()
subView.backgroundColor = .red
subView.translatesAutoresizingMaskIntoConstraints = false
stackView.addSubview(subView) // Important: addSubview() not addArrangedSubview()

// use whatever constraint method you like to 
// constrain subView to the size of stackView.
subView.topAnchor.constraint(equalTo: stackView.topAnchor).isActive = true
subView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor).isActive = true
subView.leftAnchor.constraint(equalTo: stackView.leftAnchor).isActive = true
subView.rightAnchor.constraint(equalTo: stackView.rightAnchor).isActive = true

// now add your arranged subViews...
stackView.addArrangedSubview(button1)
stackView.addArrangedSubview(button2)

iOS10에서 @Arbitur의 답변에는 색상이 설정된 후 setNeedsLayout이 필요합니다. 이것은 필요한 변경 사항입니다.

override var backgroundColor: UIColor? {
    get { return color }
    set { 
        color = newValue
        setNeedsLayout()
    }
}

다음은 스택보기 배경색을 추가하기위한 간략한 개요입니다.

class RevealViewController: UIViewController {

    @IBOutlet private weak var rootStackView: UIStackView!

모서리가 둥근 배경 뷰 만들기

private lazy var backgroundView: UIView = {
    let view = UIView()
    view.backgroundColor = .purple
    view.layer.cornerRadius = 10.0
    return view
}()

배경으로 표시하기 위해 인덱스 0에서 루트 스택 뷰의 서브 뷰 배열에 추가합니다. 그러면 스택 뷰의 정렬 된 뷰 뒤에 배치됩니다.

private func pinBackground(_ view: UIView, to stackView: UIStackView) {
    view.translatesAutoresizingMaskIntoConstraints = false
    stackView.insertSubview(view, at: 0)
    view.pin(to: stackView)
}

UIView에서 작은 확장을 사용하여 backgroundView를 스택보기의 가장자리에 고정하는 제약 조건을 추가하십시오.

public extension UIView {
  public func pin(to view: UIView) {
    NSLayoutConstraint.activate([
      leadingAnchor.constraint(equalTo: view.leadingAnchor),
      trailingAnchor.constraint(equalTo: view.trailingAnchor),
      topAnchor.constraint(equalTo: view.topAnchor),
      bottomAnchor.constraint(equalTo: view.bottomAnchor)
      ])
  }
}

부르는 pinBackground에서을viewDidLoad

override func viewDidLoad() {
  super.viewDidLoad()
  pinBackground(backgroundView, to: rootStackView)
}

여기 에서 참조하십시오 :


당신은 작은 확장을 만들 수 있습니다 UIStackView

extension UIStackView {
    func setBackgroundColor(_ color: UIColor) {
        let backgroundView = UIView(frame: .zero)
        backgroundView.backgroundColor = color
        backgroundView.translatesAutoresizingMaskIntoConstraints = false
        self.insertSubview(backgroundView, at: 0)
        NSLayoutConstraint.activate([
            backgroundView.topAnchor.constraint(equalTo: self.topAnchor),
            backgroundView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
            backgroundView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
            backgroundView.trailingAnchor.constraint(equalTo: self.trailingAnchor)
            ])
    }
}

용법:

yourStackView.setBackgroundColor(.black)

UIStackView *stackView;
UIView *stackBkg = [[UIView alloc] initWithFrame:CGRectZero];
stackBkg.backgroundColor = [UIColor redColor];
[self.view insertSubview:stackBkg belowSubview:stackView];
stackBkg.translatesAutoresizingMaskIntoConstraints = NO;
[[stackBkg.topAnchor constraintEqualToAnchor:stackView.topAnchor] setActive:YES];
[[stackBkg.bottomAnchor constraintEqualToAnchor:stackView.bottomAnchor] setActive:YES];
[[stackBkg.leftAnchor constraintEqualToAnchor:stackView.leftAnchor] setActive:YES];
[[stackBkg.rightAnchor constraintEqualToAnchor:stackView.rightAnchor] setActive:YES];

Xamarin, C # 버전 :

var stackView = new UIStackView { Axis = UILayoutConstraintAxis.Vertical };

UIView bg = new UIView(stackView.Bounds);
bg.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
bg.BackgroundColor = UIColor.White;
stackView.AddSubview(bg);

서브 클래스 UIStackView

class CustomStackView : UIStackView {

private var _bkgColor: UIColor?
override public var backgroundColor: UIColor? {
    get { return _bkgColor }
    set {
        _bkgColor = newValue
        setNeedsLayout()
    }
}

private lazy var backgroundLayer: CAShapeLayer = {
    let layer = CAShapeLayer()
    self.layer.insertSublayer(layer, at: 0)
    return layer
}()

override public func layoutSubviews() {
    super.layoutSubviews()
    backgroundLayer.path = UIBezierPath(rect: self.bounds).cgPath
    backgroundLayer.fillColor = self.backgroundColor?.cgColor
}
}

그런 다음 수업 시간에

yourStackView.backgroundColor = UIColor.lightGray

하위 레이어를 StackView에 삽입 할 수 있습니다.

@interface StackView ()
@property (nonatomic, strong, nonnull) CALayer *ly;
@end

@implementation StackView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        _ly = [CALayer new];
        [self.layer addSublayer:_ly];
    }
    return self;
}

- (void)setBackgroundColor:(UIColor *)backgroundColor {
    [super setBackgroundColor:backgroundColor];
    self.ly.backgroundColor = backgroundColor.CGColor;
}

- (void)layoutSubviews {
    self.ly.frame = self.bounds;
    [super layoutSubviews];
}

@end

서브 클래스 UI 구성 요소에 대해서는 약간 회의적입니다. 이것이 내가 사용하는 방법입니다.

struct CustomAttributeNames{
        static var _backgroundView = "_backgroundView"
    }

extension UIStackView{

var backgroundView:UIView {
        get {
            if let view = objc_getAssociatedObject(self, &CustomAttributeNames._backgroundView) as? UIView {
                return view
            }
            //Create and add
            let view = UIView(frame: .zero)
            view.translatesAutoresizingMaskIntoConstraints = false
            insertSubview(view, at: 0)
            NSLayoutConstraint.activate([
              view.topAnchor.constraint(equalTo: self.topAnchor),
              view.leadingAnchor.constraint(equalTo: self.leadingAnchor),
              view.bottomAnchor.constraint(equalTo: self.bottomAnchor),
              view.trailingAnchor.constraint(equalTo: self.trailingAnchor)
            ])

            objc_setAssociatedObject(self,
                                     &CustomAttributeNames._backgroundView,
                                     view,
                                     objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)

            return view
        }
    }
}

그리고 이것은 사용법입니다.

stackView.backgroundView.backgroundColor = .white
stackView.backgroundView.layer.borderWidth = 2.0
stackView.backgroundView.layer.borderColor = UIColor.red.cgColor
stackView.backgroundView.layer.cornerRadius = 4.0

Note: With this approach, if you want to set border, you have to set layoutMargins on the stackView so that the border is visible.


You can't add background to stackview. But what you can do is adding stackview in a view and then set background of view this will get the job done. *It will not gonna interrupt the flows of stackview. Hope this will help.


You could do it like this:

stackView.backgroundColor = UIColor.blue

By providing an extension to override the backgroundColor:

extension UIStackView {

    override open var backgroundColor: UIColor? {

        get {
            return super.backgroundColor
        }

        set {

            super.backgroundColor = newValue

            let tag = -9999
            for view in subviews where view.tag == tag {
                view.removeFromSuperview()
            }

            let subView = UIView()
            subView.tag = tag
            subView.backgroundColor = newValue
            subView.translatesAutoresizingMaskIntoConstraints = false
            self.addSubview(subView)
            subView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
            subView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
            subView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
            subView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
        }

    }

}

참고URL : https://stackoverflow.com/questions/34868344/how-to-change-the-background-color-of-uistackview

반응형