티스토리 뷰
1. Component 공부
(1) ViewController.swift
import UIKit
class ViewController: UIViewController {
let textField = UITextField()
let button = UIButton(type: .system)
let stepper = UIStepper()
override func viewDidLoad() {
super.viewDidLoad()
title = "Title"
// navigationItem.title = "New Title"
let image = UIImage(systemName: "face.smiling")
let imageView = UIImageView(image: image)
navigationItem.titleView = imageView
view.addSubview(textField)
view.addSubview(button)
view.addSubview(stepper)
textField.frame = CGRect(x: view.frame.midX - 100, y: view.frame.midY - 30, width: 200, height: 40)
textField.layer.borderColor = UIColor.gray.cgColor
textField.layer.borderWidth = 0.5
textField.layer.cornerRadius = 4
textField.delegate = self
button.setTitle("Next", for: .normal)
button.sizeToFit()
let buttonWidth = button.frame.width
button.frame.origin = CGPoint(x: view.frame.midX - buttonWidth / 2, y: view.frame.midY + 30)
button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
let stpperWidth = stepper.frame.width
stepper.frame.origin = CGPoint(x: view.frame.midX - stpperWidth / 2 , y: view.frame.midY - 100)
stepper.addTarget(self, action: #selector(stepperChanged(_:)), for: .valueChanged)
}
@objc func buttonTapped(_ sender: UIButton) {
let secondVC = SecondViewController()
secondVC.label.text = textField.text ?? "🤢🤢🤢"
present(secondVC, animated: true)
}
@objc func stepperChanged(_ sender: UIStepper) {
}
}
extension ViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
print(textField.text)
return true
//return false -> 더 이상 입력이 되지 않음. (예를들어 글자수에 따라 더 이상 입력되지 않게 하기 위해서 사용할 수 있음)
}
}
① TextField Delegate
- delegate = self 를 잊지말 것
- textField(_:shouldChangeCharactersIn:replacementString:) : 실시간으로 textField에 입력되는 text를 받아오는 delegate method. true를 리턴해야 작동함
(2) SecondViewController.swift
import UIKit
class SecondViewController: UIViewController {
let label = UILabel()
let backButton = UIButton(type: .system)
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(label)
label.frame = CGRect(x: view.frame.midX - 100, y: view.frame.midY - 20, width: 200, height: 40)
label.backgroundColor = .purple.withAlphaComponent(0.3)
label.layer.borderWidth = 1
label.layer.cornerRadius = 4
label.textAlignment = .center
view.addSubview(backButton)
backButton.setTitle("Alert", for: .normal)
backButton.sizeToFit()
let buttonWidth = backButton.frame.width
backButton.frame.origin = CGPoint(x: view.frame.midX - buttonWidth / 2, y: view.frame.midY + 30)
backButton.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
}
@objc func buttonTapped(_ sender: UIButton) {
let alert = UIAlertController(title: "🚨경고🚨", message: "마지막 창입니다.", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "취소", style: .cancel)
let confirmAction = UIAlertAction(title: "확인", style: .default) { _ in
print(alert.textFields?.first?.text)
}
alert.addTextField()
// alert.addTextField { textField in
// textField.keyboardType = .numberPad
// }
alert.addAction(cancelAction)
alert.addAction(confirmAction)
present(alert, animated: true)
}
}
① UIAlertController
- alert에 textField를 넣어줄 때는 간단하게 alert.textField()만 해주면 됨. 여기서 클로저도 추가 가능 (주석 참고)
2. (지난 주에 이어) Ratings project
(1) AddPlayerViewController.swift
import UIKit
class AddPlayerViewController: UIViewController {
// let들은 순서가 보장되지 않음
// 보장하기 위해 lazy var를 사용
// let layout = UICollectionViewLayout()
// lazy var collection = UICollectionView(frame: .zero, collectionViewLayout: layout)
let tableView = UITableView(frame: .zero, style: .grouped)
lazy var cancelBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(barButtonItemTapped(_:)))
lazy var doneBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(barButtonItemTapped(_:)))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
tableView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
tableView.dataSource = self
title = "Add Player"
tableView.register(AddPlayerTextFieldTableViewCell.self, forCellReuseIdentifier: AddPlayerTextFieldTableViewCell.identifier)
navigationItem.leftBarButtonItem = cancelBarButtonItem
navigationItem.rightBarButtonItem = doneBarButtonItem
}
@objc func barButtonItemTapped(_ sender: UIBarButtonItem) {
// lazy var를 이용해야 함
// 함수가 불릴 때 버튼은 생성되지 않음
switch sender {
case cancelBarButtonItem:
print("cancle")
case doneBarButtonItem:
print("don")
default:
break
}
}
}
extension AddPlayerViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0 {
return "PLAYER NAME"
}
return nil
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: AddPlayerTextFieldTableViewCell.identifier, for: indexPath) as? AddPlayerTextFieldTableViewCell else { fatalError() }
if indexPath.section == 0 {
return cell
} else {
let basicCell = UITableViewCell()
basicCell.textLabel?.text = "Game"
basicCell.accessoryType = .disclosureIndicator
let label = UILabel.init(frame: CGRect(x:0,y:0,width:100,height:20))
label.text = "Detail"
basicCell.accessoryView = label
return basicCell
}
}
}
① cancelBarButtonItem과 doneBarButtonItem을 lazy var로 선언하지 않으면 버튼 액션(barButtomItemTapped)에서 sender가 nil값이 됨.
- let으로 선언했던 BarButtonItem들이 함수(barButtomItemTapped)보다 생성되기 때문임.
- 해당 변수들(cancelBarButtonItem, doneBarButtonItem)을 lazy로 선언해주면 실행 순서가 보장되기 때문에 원하는대로 sender 값이 들어옴
- collectionView를 만들 때도 마찬가지임. layout 상수가 collectionView를 초기화할 때 필요한 요소인데, 생성 순서가 보장되지 않기 때문에 collectionView를 지연저장 속성으로 만들어서 생성 순서를 보장하면 됨
class ViewController: UIViewController {
let layout = UICollectionViewLayout()
lazy var collection = UICollectionView(frame: .zero, collectionViewLayout: layout)
override func viewDidLoad() {
super.viewDidLoad()
}
}
(2) AddPlayerTextFieldTableViewCell.swift
import UIKit
class AddPlayerTextFieldTableViewCell: UITableViewCell {
static let identifier = "AddPlayerTextFieldTableViewCell"
let textField = UITextField()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(textField)
textField.frame = CGRect(x: 0, y: 0, width: contentView.frame.width, height: contentView.frame.height)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
<오늘의 배운 점>
1. UIAlertContoroller에 textField 추가하는 방법과 handler 사용
2. frame으로 UI짜기 (중심 잡기)
3. lazy var의 실제 사용
'순진이의 하루 > study정리' 카테고리의 다른 글
7. UserDefaults, Animation_2022.08.24 (0) | 2022.08.24 |
---|---|
6. CollectionView code로 짜기, Delegate Pattern_2022.08.22 (0) | 2022.08.22 |
4. CustomView_2022.08.10 (0) | 2022.08.09 |
3. 스토리보드 삭제, tableView cell configuration_2022.08.08 (0) | 2022.08.04 |
1. 스토리보드 삭제_2022.08.01 (0) | 2022.08.03 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크