Search

[실험실] Custom View를 이해해보고 싶어요(1편)

Layout 잡는 함수
Custom View with Xib
Xib로 만든건 죄다 안됨...(Override 문제 였음)
import UIKit class MyView: UIView { @IBOutlet weak var customLabel: UILabel! @IBOutlet weak var customView: UIView! @IBInspectable var customTime: String = "남은 시간 10분" { didSet { customLabel.text = customTime } } // 코드로 짤 때는 여기를 건드려야 함. override init(frame: CGRect) { super.init(frame: frame) xibSetup() } // storyboard로 짤 때는 여기를 건드려야 함 required init?(coder: NSCoder) { super.init(coder: coder) xibSetup() } func xibSetup() { let nib = Bundle.main.loadNibNamed("MyView", owner: self, options: nil)?[0] as! UIView nib.frame = self.bounds addSubview(nib) // Bundle.main.loadNibNamed("MyView", owner: self, options: nil) // addSubview(customView) // customView.frame = bounds // customView.autoresizingMask = [.flexibleWidth, .flexibleHeight] // customView.layer.cornerRadius = customView.bounds.height / 2 } }
Swift
복사
// xib로 유일하게 성공 (ViewController에 올려줌) func customInit() { if let sview = Bundle.main.loadNibNamed("XibCustomView", owner: nil, options: nil)?.first as? UIView { sview.frame = self.view.bounds view.addSubview(sview) } }
Swift
복사
// // Extension+UIView.swift // LetsCustomView // // Created by SHIN YOON AH on 2021/05/24. // import UIKit extension UIView { func loadView(nibName: String) -> UIView? { let bundle = Bundle(for: type(of: self)) let nib = UINib(nibName: nibName, bundle: bundle) return nib.instantiate(withOwner: self, options: nil).first as? UIView } var mainView: UIView? { return subviews.first } }
Swift
복사
Custom View with Code
// // CodeCustomView.swift // LetsCustomView // // Created by SHIN YOON AH on 2021/05/24. // import UIKit class CodeCustomView: UIView { let imageView = UIImageView() let nameLabel = UILabel() let ageLabel = UILabel() let gender = UILabel() override init(frame: CGRect) { super.init(frame: frame) ab() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func ab() { print("Inti") backgroundColor = .cyan addSubview(imageView) addSubview(nameLabel) addSubview(ageLabel) addSubview(gender) imageView.translatesAutoresizingMaskIntoConstraints = false nameLabel.translatesAutoresizingMaskIntoConstraints = false ageLabel.translatesAutoresizingMaskIntoConstraints = false gender.translatesAutoresizingMaskIntoConstraints = false } }
Swift
복사
코드로 구현한 모습, required init은 상관쓰지 말자.
Custom Button
let viewModel = MyCustomButtonViewModel(title: "Purchase", subtitle: "$1.99/mo", imageName: "cart") let myButton = MyCustomButton(with: viewModel) myButton.frame = CGRect(x: 0, y: 0, width: 200, height: 60) myButton.backgroundColor = .red view.addSubview(myButton) myButton.center = view.center myButton.configure(with: viewModel)
Swift
복사
// // MyCustomButton.swift // LetsCustomView // // Created by SHIN YOON AH on 2021/05/24. // import UIKit class MyCustomButton: UIButton { private let myTitleLabel: UILabel = { let label = UILabel() label.numberOfLines = 1 label.textAlignment = .center return label }() private let mySubtitleLabel: UILabel = { let label = UILabel() label.numberOfLines = 1 label.textAlignment = .center return label }() private let myIconView: UIImageView = { let imageView = UIImageView() imageView.contentMode = .scaleAspectFit imageView.tintColor = .white return imageView }() private var viewModel: MyCustomButtonViewModel? override init(frame: CGRect) { self.viewModel = nil super.init(frame: frame) } init(with viewModel: MyCustomButtonViewModel) { self.viewModel = viewModel super.init(frame: .zero) addSubviews() configure(with: viewModel) } private func addSubviews() { guard !myTitleLabel.isDescendant(of: self) else { return } addSubview(myTitleLabel) addSubview(mySubtitleLabel) addSubview(myIconView) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } public func configure(with viewMode: MyCustomButtonViewModel) { layer.masksToBounds = true layer.cornerRadius = 8 layer.borderColor = UIColor.secondarySystemBackground.cgColor layer.borderWidth = 1.5 addSubviews() myTitleLabel.text = viewModel?.title mySubtitleLabel.text = viewModel?.subtitle myIconView.image = UIImage(systemName: viewModel?.imageName ?? "") } override func layoutSubviews() { super.layoutSubviews() /* [ ] [title] [i] [ ] [subtitle] */ myIconView.frame = CGRect( x: 5, y: 5, width: 50, height: self.frame.height ).integral myTitleLabel.frame = CGRect( x: 60, y: 5, width: frame.width-65, height: (frame.height-10)/2 ).integral mySubtitleLabel.frame = CGRect( x: 60, y: (frame.height+10)/2, width: frame.width-65, height: (frame.height-10)/2 ).integral } }
Swift
복사
// // MyCustomButtonViewModel.swift // LetsCustomView // // Created by SHIN YOON AH on 2021/05/24. // import Foundation struct MyCustomButtonViewModel { let title: String let subtitle: String let imageName: String }
Swift
복사