티스토리 뷰
이전에 커스텀한 버튼을 만든 적이 있었는데요 저는 제약조건을 수정해서 확장시켰는데
깃을 보다가 Ale Patron이 분의 방식이 좋아 보여서 기록해놓으려 합니다.
기존 코드에서 맘대로 조금 수정을 했습니다.
버튼이 정중앙에 배치되어있는데 오른쪽 하단으로 옮겼고 색상을 변경했습니다.
버튼의 텍스트와 함수명을 변경했습니다.
버튼 사이즈 상수는 ButtonPanelView에서만 사용되고 있어 클래스 내부로 들고 왔습니다.
(내부로 들고 오면서 접근 제어자 fileprivate에서 private로 변경했습니다)
프로토콜은 클래스만 사용할 수 있도록 class로 수정했습니다.
버튼에 쉐도우 레이어는 제거했습니다.
그럼 다시 시작.
class ButtonPanelView: UIView {
private let buttonSize: CGFloat = 50
weak var delegate: ButtonPanelDelegate?
lazy var menuButton: UIButton = {
let button = UIButton(frame: .zero)
button.setTitle("⭕️", for: .normal)
button.backgroundColor = .clear
button.layer.cornerRadius = buttonSize / 2
button.addTarget(
self, action: #selector(tappedPanelButton(_:)), for: .touchUpInside)
return button
}()
lazy var firstButton: UIButton = {
let button = UIButton(frame: .zero)
button.setTitle("1️⃣", for: .normal)
button.layer.cornerRadius = buttonSize / 2
button.isHidden = true
button.addTarget(
self, action: #selector(tappedExpadedButton(_:)), for: .touchUpInside)
return button
}()
lazy var secondButton: UIButton = {
let button = UIButton(frame: .zero)
button.setTitle("2️⃣", for: .normal)
button.layer.cornerRadius = buttonSize / 2
button.isHidden = true
button.addTarget(
self, action: #selector(tappedExpadedButton(_:)), for: .touchUpInside)
return button
}()
lazy var expandedStackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.isHidden = true
stackView.addArrangedSubview(firstButton)
stackView.addArrangedSubview(secondButton)
return stackView
}()
lazy var containerStackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.addArrangedSubview(expandedStackView)
stackView.addArrangedSubview(menuButton)
return stackView
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.lightGray
layer.cornerRadius = buttonSize / 2
addSubview(containerStackView)
setConstraints()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setConstraints() {
menuButton.translatesAutoresizingMaskIntoConstraints = false
menuButton.widthAnchor.constraint(equalToConstant: buttonSize).isActive = true
menuButton.heightAnchor.constraint(equalToConstant: buttonSize).isActive = true
firstButton.translatesAutoresizingMaskIntoConstraints = false
firstButton.widthAnchor.constraint(equalToConstant: buttonSize).isActive = true
firstButton.heightAnchor.constraint(equalToConstant: buttonSize).isActive = true
secondButton.translatesAutoresizingMaskIntoConstraints = false
secondButton.widthAnchor.constraint(equalToConstant: buttonSize).isActive = true
secondButton.heightAnchor.constraint(equalToConstant: buttonSize).isActive = true
containerStackView.translatesAutoresizingMaskIntoConstraints = false
containerStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
containerStackView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
translatesAutoresizingMaskIntoConstraints = false
self.widthAnchor.constraint(equalTo: containerStackView.widthAnchor).isActive = true
self.heightAnchor.constraint(equalTo: containerStackView.heightAnchor).isActive = true
}
}
xib를 사용해서 초기화하지 않기 때문에 required init?(coder: NSCoder)는 비워져 있습니다.
버튼 사이즈는 원하는 크기로 두면 됩니다.
아래에서 버튼 사이즈를 사용하기 때문에 따로 상수로 사용하는 게 좋습니다.
delegate는 버튼을 눌렀을 때 이벤트를 전송하기 위해 존재합니다.
그리고 각각의 버튼을 선언했습니다.
필요한 버튼은 총 3개로 펼치기 전에 보이는 버튼과 펼쳤을 때 추가로 2개의 버튼이 필요합니다.
그리고 펼쳤을 때 2개의 버튼을 감싸는 expandedStackView를 생성하고 숨김으로 처리했습니다.
그리고 총 3개의 버튼을 감싸는 containerStackView를 생성합니다.
이 containerStackView에는 1개의 버튼과 expendedStackView가 들어갑니다.
setConstraints함수 내에서는 각각의 제약조건을 잡습니다.
이벤트 전송을 위해 델리게이트 프로토콜을 만들고 사용합니다.
protocol ButtonPanelDelegate: class {
func didTapButtonWithText(_ text: String)
}
ButtonPanelDelegate프로토콜은 ViewController에서 채택하고 이벤트를 받습니다.
뷰 컨트롤러에서 버튼을 생성해주고 뷰에 넣어주고 제약을 잡아줍니다.
class ViewController: UIViewController {
private let buttonPanelView = ButtonPanelView()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
setupConstraint()
}
func setupUI() {
buttonPanelView.delegate = self
view.addSubview(buttonPanelView)
}
func setupConstraint() {
buttonPanelView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -16).isActive = true
buttonPanelView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -48).isActive = true
}
}
extension ViewController: ButtonPanelDelegate {
func didTapButtonWithText(_ text: String) {
print(text)
}
}
extension을 통해 어떤 버튼이 클릭되었는지 문자열을 전송함으로 파악할 수 있습니다.
'Tech > iOS' 카테고리의 다른 글
iOS 애드몹 연결하기 (0) | 2022.03.04 |
---|---|
시뮬레이터에 이미지, 동영상 넣기 (0) | 2021.05.01 |
Adopting Picture in Picture in a Custom Player (0) | 2021.01.22 |
UIKit와 Foundation프레임워크 선언 (0) | 2020.12.28 |
AVPlayerViewController 살펴보기 (0) | 2020.11.10 |
- Total
- Today
- Yesterday
- Algorithm
- objc
- 애니메이션
- iOS SwiftUI
- ARC
- string
- ios
- 독서
- rxswift
- Animation
- objective-c
- Xcode
- swiftUI
- Deep learning
- 스위프트
- stanford SwiftUI
- ReactiveX
- 딥러닝
- leetcode
- swift5
- 머신러닝
- 책
- RX
- 책 후기
- 책 추천
- wwdc
- 스위프트UI
- SWIFT
- 알고리즘
- 문자열
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |