애플 하면 부드러운 애니메이션 아니겠는가..
스택뷰를 코드로 작성해 보고, 애니메이션을 통해 부드럽게 추가/제거 하는 연습을 해봤다.
(애니메이션을 적용하지 않으면 그냥 툭 툭 뷰가 추가/제거 된다. 별로 보기 안좋다.)
아래는 .gif라 좀 끊기지만 시뮬레이터에서는 부드럽게 잘 작동한다.
//
// StackViewController.swift
// codeLayout
//
// Created by Toughie on 2023/03/27.
//
import UIKit
class StackViewController: UIViewController {
var vertical: UIStackView = UIStackView()
override func viewDidLoad() {
super.viewDidLoad()
vertical.axis = .vertical
vertical.translatesAutoresizingMaskIntoConstraints = false
vertical.spacing = 10
vertical.distribution = .fillEqually
view.addSubview(vertical)
//버튼을 묶을 HStack
let horizontal = UIStackView()
horizontal.axis = .horizontal
horizontal.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(horizontal)
let addButton = UIButton()
addButton.setTitle("Add", for: .normal)
addButton.setTitleColor(.blue, for: .normal)
addButton.addTarget(self,
action: #selector(addView),
for: .touchUpInside)
let removeButton = UIButton()
removeButton.setTitle("Remove", for: .normal)
removeButton.setTitleColor(.red, for: .normal)
removeButton.addTarget(self,
action: #selector(removeView),
for: .touchUpInside)
horizontal.addArrangedSubview(addButton)
horizontal.addArrangedSubview(removeButton)
horizontal.distribution = .fillEqually
horizontal.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
horizontal.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
horizontal.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
vertical.leadingAnchor.constraint(equalTo: horizontal.leadingAnchor).isActive = true
vertical.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
vertical.trailingAnchor.constraint(equalTo: horizontal.trailingAnchor).isActive = true
vertical.bottomAnchor.constraint(equalTo: horizontal.topAnchor).isActive = true
}
@objc func addView() {
let view = UIView()
let colors: [UIColor] = [UIColor(ciColor: .red),
UIColor(ciColor: .magenta),
UIColor(ciColor: .blue),
UIColor(ciColor: .yellow),
UIColor(ciColor: .gray),
UIColor(ciColor: .cyan),
UIColor(ciColor: .green)]
let randomInt = Int.random(in: 0..<colors.count)
view.backgroundColor = colors[randomInt]
view.isHidden = true //우선 뷰를 숨겨뒀다가..
vertical.addArrangedSubview(view)
UIView.animate(withDuration: 0.3) {
view.isHidden = false
}
print("add")
}
@objc func removeView() {
guard let last = vertical.arrangedSubviews.last else { return }
UIView.animate(withDuration: 0.3) {
last.isHidden = true
} completion: { (_) in
self.vertical.removeArrangedSubview(last)
}
}
}
원래는 단색의 뷰가 추가되는 예시였는데.. 심심해서 알록달록하게 해보려고 코드를 수정했다.
분명 더 좋게 짤 수도 있겠지만.. 그리 중요한 부분이 아니라 생각해서
그냥 컬러를 담는 배열을 만들고
랜덤 숫자를 뽑아
배열에 서브스크립트로 접근하는 방식이다.
UIColor타입을 배열에 어떻게 담지? 했는데 아래와 같은식으로 해도 일단 잘 된다.
UIColor(ciColor: .cyan)
애니메이션을 적용하기 전에 view를 숨기는 .isHidden 프로퍼티가 있음을 기억하자.
또한 버튼에 기능을 연결하기 위해 필요한 셀렉터에 대해 간단하게 알아보자.
#selector
주로 특정 이벤트를 함수/메서드에 연결시키는 방법을 말한다.
@objc func doSomething() {
print("I like Swift")
}
button.addTarget(self, action: #selector(doSomething), for: touchUpInside)
셀렉터는 어떤 함수/메서드를 가리키는 연결고리 정도로 생각하면 좋다.
다만 selector안에 들어가는 함수/메서드 앞에는 @objc 어트리뷰트를 붙여줘야 한다.
@objc는 Swift 메서드, 속성 또는 클래스가 Objective-C 코드임을 나타내는 것이다.
이전 옵젝씨에서 사용하던 메서드나 프로퍼티를 사용할 때 필요.(대표적으로 셀렉터 같이)
옵젝C에서 Swift로 넘어가는 과정에서 남은 잔재? 정도로 보인다.
셀렉터 몇 번 써보다 보면 그냥 자동으로 @objc 붙여야지 라고 생각하게 된다.
[학습 소스]
공식문서, 야곰 오토레이아웃 정복하기 강의
'UIKit > AutoLayout' 카테고리의 다른 글
11. Safe Area , Layout Margins (0) | 2023.03.27 |
---|---|
10. Size Class ? (0) | 2023.03.27 |
8. 코드로 오토레이아웃 잡기 (0) | 2023.03.26 |
7. SuperView, Safe Area (0) | 2023.03.26 |
6. Debugging Auto Layout (0) | 2023.03.26 |