programing

UIStack View의 배경색을 변경하는 방법

stoneblock 2023. 4. 19. 21:53

UIStack View의 배경색을 변경하는 방법

는 이 말을 요.UIStackViewStoryboard inspector의 배경은 투명에서 흰색으로 표시되지만 시뮬레이션 시 스택 뷰의 배경색은 여전히 선명하게 표시됩니다.
UIStackView

수는 없어요.UIStackView즉, '동일화'는drawRect()는 호출되지 않으며 배경색은 무시됩니다. 배경색을 경우 를 다른 에 배치하는 을 검토해 .UIView츠요시

여기서의 참조.

편집:

subView에 할 수 .UIStackView여기서 또는 이 답변(아래)에서 설명한 바와 같이 색상을 지정합니다.아래를 확인해 주세요extension경우 : 우 for :

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다음과 같이 서브뷰(배치되어 있지 않음)로 표시됩니다.

extension UIStackView {

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

}

iOS 14부터는 UIStack View가 배경색을 렌더링합니다.스토리보드에서 배경 속성을 사용하여 UIStackView의 배경을 설정할 수도 있습니다.

여기에 이미지 설명 입력

또는 다음과 같은 코드:

if #available(iOS 14.0, *) {
    stackView.backgroundColor = .green
} else {
    // Fallback for older versions of iOS
}

가장도 덜 진부한 은 마, 기, 킹, 킹, 킹, 킹, 킹, 킹, 킹, 킹, 킹, 킹, 킹, y, 킹, y, 킹, y, y, y, the, the, the, the the, ,UIStackViewUIView뷰의 배경색을 설정합니다.

또, 이러한 2개의 뷰간에 자동 레이아웃의 제약을 적절히 설정하는 것도 잊지 말아 주세요. ;-)

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)

를 위한 공식 방법은 하여 빈 뷰를 스택뷰에 입니다.DR: 이를 위한 공식 방법은 스택뷰에 빈 뷰를 추가하는 것입니다.addSubview:대신 추가된 뷰 배경을 설정합니다.

:: UBack View는 레이아웃만 하지 않는 특수 UVIUView(UBack View)입니다.UIStackView는 레이아웃만 그리는 특수한 UIView 서브클래스입니다.그래서 많은 재산은 평소처럼 작동하지 않을 것이다.많은 특성이 정상적으로 작동하지 않을 것입니다.그리고 UBack View가 배열된 하위 보기를 배치하면 한 렬 에 만 문 with 된 순 u 뷰 웃 가 view 아 히 기 하 이addSubview:method, 구속조건 및 배경색을 설정합니다.이것은 WWDC 세션에서 원하는 것을 얻기 위한 공식 방법입니다.

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)

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

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에서 작은 확장을 사용하여 background View를 스택 뷰의 가장자리에 고정하는 구속조건을 추가합니다.

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)
      ])
  }
}

call the 를 호출하다pinBackground부에서viewDidLoad

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

출처: HERE

iOS10에서 @Arbitur의 답변에는 색상 설정 후 setNeedsLayout이 필요합니다.필요한 변경은 다음과 같습니다.

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

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

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];

서브클래스 UIStack View

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

주의: 이 접근법에서는 경계를 설정하려면 , 다음의 설정을 실시할 필요가 있습니다.layoutMargins되도록 합니다.stackView는 되도록 합니다.

스택 뷰에 배경을 추가할 수 없습니다.그러나 뷰에 스택 뷰를 추가한 후 뷰 배경을 설정하면 작업이 완료됩니다.*스택 뷰의 흐름은 중단되지 않습니다.이게 도움이 되길 바라.

를 할 수요.StackView 이렇게요.

class StackView: UIStackView {
    lazy var backgroundView: UIView = {
        let otherView = UIView()
        addPinedSubview(otherView)
        return otherView
    }()
}

extension UIView {
    func addPinedSubview(_ otherView: UIView) {
        addSubview(otherView)
        otherView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            otherView.trailingAnchor.constraint(equalTo: trailingAnchor),
            otherView.topAnchor.constraint(equalTo: topAnchor),
            otherView.heightAnchor.constraint(equalTo: heightAnchor),
            otherView.widthAnchor.constraint(equalTo: widthAnchor),
        ])
    }
}

다음과 같이 사용할 수 있습니다.

let stackView = StackView()
stackView.backgroundView.backgroundColor = UIColor.lightGray

은 확장 더 .func addBackground(color: UIColor)실제로 전화.stackView.backgroundView.backgroundColor = ...또한 배경색을 여러 번 설정/변경해도 스택뷰에 여러 개의 서브뷰가 삽입되지 않습니다.

디자이너 자체에서 제어하려면 이 확장을 스택 보기에 추가하십시오.

 @IBInspectable var customBackgroundColor: UIColor?{
     get{
        return backgroundColor
     }
     set{
        backgroundColor = newValue
         let subview = UIView(frame: bounds)
         subview.backgroundColor = newValue
         subview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
         insertSubview(subview, at: 0)
     }
 }

좋은 답변이 있지만 완벽하지 않다는 것을 깨달았습니다.그 중 가장 좋은 것을 바탕으로 한 버전을 다음에 나타냅니다.

    /// This extension addes missing background color to stack views on iOS 13 and earlier
extension UIStackView {
    
    private struct CustomAttributeNames {
        static var _backgroundView = "_backgroundView"
    }
    
    @IBInspectable var customBackgroundColor: UIColor? {
        get { backgroundColor }
        set { setBackgroundColor(newValue) }
    }
    
    var backgroundView: UIView {
        if let view = objc_getAssociatedObject(self, &CustomAttributeNames._backgroundView) as? UIView {
            return view
        }
        
        let view = UIView(frame: bounds)
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        
        insertSubview(view, at: 0)
        
        objc_setAssociatedObject(self,
                                 &CustomAttributeNames._backgroundView,
                                 view,
                                 objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        
        return view
    }
    
    func setBackgroundColor(_ color: UIColor?) {
        backgroundColor = color
        backgroundView.backgroundColor = color
    }
}

다음과 같이 할 수 있습니다.

stackView.backgroundColor = UIColor.blue

" " " " " 를 위한 함"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
        }

    }

}

Apple의 설명에 따르면 스택 뷰 자체는 iOS 13에서 렌더링되지 않으며, 그 목적은 정렬된 서브뷰를 관리하는 것입니다.

UIStackView는 UIView의 비렌더링 서브클래스입니다.즉, 독자적인 사용자 인터페이스를 제공하지 않습니다.대신 배열된 뷰의 위치와 크기만 관리합니다.따라서 backgroundColor 등의 일부 속성은 스택뷰에 영향을 주지 않습니다.

iOS 13 이하에서 배경색을 수정하기 위한 확장자를 만들면 이 문제를 해결할 수 있습니다.

import UIKit

extension UIStackView {
    // MARK: Stored properties

    private enum Keys {
        static var backgroundColorView: UInt8 = 0
    }

    private var backgroundColorView: UIView? {
        get {
            objc_getAssociatedObject(self, &Keys.backgroundColorView) as? UIView
        }
        set {
            objc_setAssociatedObject(self, &Keys.backgroundColorView, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    override open var backgroundColor: UIColor? {
        didSet {
            // UIKit already support setting background color in iOS 14 or above
            guard #available(iOS 14.0, *) else {
                // fix setting background color directly to stackview by add a background view
                if backgroundColorView == nil {
                    let backgroundColorView = UIView(frame: bounds)
                    backgroundColorView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
                    insertSubview(backgroundColorView, at: 0)
                    self.backgroundColorView = backgroundColorView
                }
                backgroundColorView?.backgroundColor = backgroundColor
                return
            }
        }
    }
}

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