관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 내부 content size에 따라 superview 크기도 변하는 동적 뷰 본문

iOS 응용 (swift)

[iOS - swift] 내부 content size에 따라 superview 크기도 변하는 동적 뷰

jake-kim 2021. 7. 30. 23:59

  • MyDynamicView의 내부 컨텐츠(text)가 변할때 마다 컨텐츠를 감싸고 있는 view도 동시에 조정
class ViewController: UIViewController {

    lazy var myView: MyDynamicView = {
        let view = MyDynamicView()
        view.text = "123"

        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(myView)
        myView.center = view.center

        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
            self.myView.text = "1"
            self.myView.center = self.view.center
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
            self.myView.text = "123213123"
            self.myView.center = self.view.center
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
            self.myView.text = "123"
            self.myView.center = self.view.center
        }
    }
}

sizeToFit, intrinsicContentSIze 사용

  • 개념은 여기 참고
  • 핵심은 autolayout을 사용하지 않고 sizeToFit, intrinsicContentSIze 사용하여 frame값 구하기
    • autolayout을 사용하면 지정한 frame값이 무시되는 것을 주의
  • text가 변할때: sizeToFit() 사용
  • 외부 뷰 크기 조정: text를 가진 label의 intrinsicConentSize를 통해 size를 구하여 외부 뷰의 frame값 조정
titleLabel.sizeToFit()
let viewSize = titleLabel.intrinsicContentSize
let width = viewSize.width + 58
let height = viewSize.height + 48
frame.size = CGSize(width: width, height: height)

titleLabel.center = CGPoint(x: width / 2, y: height / 2)
  • 전체 코드
class MyDynamicView: UIView {

    var text: String? {
        didSet{ bind() }
    }

    private lazy var titleLabel: UILabel = {
        let label = UILabel()
        label.textColor = .blue

        return label
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)

        addsubviews()
        setupView()
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemeneted")
    }

    private func addsubviews() {
        addSubview(titleLabel)
    }

    private func setupView() {
        backgroundColor = .lightGray

        layer.cornerRadius = 14.0
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 3.0, height: 3.0)
        layer.shadowOpacity = 0.1
        layer.shadowRadius = 3.0
    }

    private func bind() {
        titleLabel.text = text
        setupDynamicLayout()
    }

    private func setupDynamicLayout() {
        titleLabel.sizeToFit()
        let viewSize = titleLabel.intrinsicContentSize
        let width = viewSize.width + 58
        let height = viewSize.height + 48
        frame.size = CGSize(width: width, height: height)

        titleLabel.center = CGPoint(x: width / 2, y: height / 2)
    }
}
Comments