Uber클론코딩을 하다가 알게된 것들
ui를 그리다보면 사실 중복되는 view들이 많아서 따로 uiview파일을 만들어서 view를 만드는데 이 강의에서는 아얘 extention으로 빼서 만들길래 뭔가 layout까지 extenion에 함수를 만들어서 정의 할수가있나라는 생각이 들었는데 사실 UIView로 만드나 extesion으로 만드나 큰 차이가 없다는걸 알게되었다
extension UIView {
func inputContainerView(image: UIImage, textfield: UITextField? = nil, segmentControl: UISegmentedControl? = nil) {
let imageView: UIImageView = UIImageView().then {
$0.image = image
$0.alpha = 0.87
}
let seperatorView: UIView = UIView().then {
$0.backgroundColor = .lightGray
}
self.addSubview(imageView)
if let textfield = textfield {
레이아웃코드들
}
if let segmentControl = segmentControl {
레이아웃 코드들
}
레이아웃 코드들
}
}
이런식으로 만드는건 보통 Button을 정의하거나 그럴때 uibutton을 extension으로 해서 만들었는데 강사님은 uiview를 extesion으로 추가정의하고 오히려 button을 따로 파일을 만들어서 작업했다
class AuthButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
setTitle("Log In", for: .normal)
setTitleColor(UIColor(white: 1, alpha: 0.5), for: .normal)
backgroundColor = .mainBlueTint
layer.cornerRadius = 5
titleLabel?.font = .boldSystemFont(ofSize: 20)
heightAnchor.constraint(equalToConstant: 50).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
뭐가 맞고 틀리고 좋나 나쁘다가 아니라 스타일 차이인거같다
optional에 대해서 공부를 해보려고 기존에 들었던 강의들하고 구글링을 해봤다. 사실 기존에 들었던강의 자료에서 하나의 문구때문에 이걸 공부하게 된건데 그 문구가 뭐냐면
nil - 값이 없음을 나타내는 키워드 (실제 값이 없음이 아님)
이거다 나는 당연히 nil은 실제로 값이 없는거라고 생각을 했는데 그게아니라고...? 아니그럼 대체 뭐지 라고 생각을하는찰나에 값이없음을 나타내는키워드인데 실제로 값없음이 아니라고...? 이게 대체 무슨말이지....
라는 생각이 들어서 optional부터 공부를 해봤다
우선 옵셔널의 정의를 보면 enum타입이다...? 그러면 이건 case가 존재한다는건데...?하고 알아보니
이렇게 none case와 some case로 나뉘어져있다 당연히none은 값이없는 case일거고 some은 연관값이 들어있는 값일거다
그래서 optional은 기본적으로 값이 없는 케이스와 값이 있는 케이스를 반환해준다.
그리고 .none == nil인거다
원래 정말 메모리에 값이 없는상태면 오류가 발생한다 하지만 swift에서는 이러한 문제를 해결하기 위해 nil이라는 값을 넣어준거다.
그러면 메모리에 nil이라는 자체가 들어있기 때문에 값이 없지만(nil을 언래핑하면 값없음이다) nil이라는 값이없음을 나타내는 키워드자체는 들어있기 때문에 오류를 발생시키지 않을 수 있다.
optional pattern이라는게 있길래 좀 알아봤다
방금 optional은 enum이고 이때 값이있으면 .some 케이스에 연관값으로 들어있는 값이 실제값이라고 이야기했었다 그래서 이걸 벗기고 싶을때 여러가지 언래핑방식을 사용하지만 이렇게도 사용할 수 있다
if case .some(let n) = name {
print(n)
}
근데 옵셔널 패턴이라는건 위와같이 사용하는게 아니라
if case let n? = name {
print(n)
}
이렇게 사용하는거다 근데 이것도 사실은 보면 모양만 바뀌었지 옵셔널바인딩이랑 크게 다를게없다
하지만 이걸로 for문을 돌린다면 이야기가 조금은 달라진다
예를들어서 아래와같은 array가 존재한다고 하자
let array: [String?] = [nil, "a", "b", nil]
만약에 옵셔널바인딩으로 for문을 돌리면서 nil을 빼려면
var count = 0
for i in array {
count += 1
guard let string = string else { continue }
print(string)
}
print(count)
이렇게 하면 count는 4번이 된다 즉 반복을 array의 갯수만큼 한거다
하지만 옵셔널 체이닝을 사용한다면?
var count = 0
for case let string? in array {
count += 1
print(string)
}
print(count)
이렇게 하면 count는 2번이 된다 결과는 같지만 반복문의 실행횟수가 줄어든다.
버튼을 만드는데 버튼 title을 단어에따라 색과 폰트를 다르게 하고싶은 경우 아래처럼 코드를 구성하면 된다
private lazy var dontHaveAccountButton: UIButton = UIButton(type: .system).then {
let attributedTitle = NSMutableAttributedString(string: "Don't have an account? ",
attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16),
NSAttributedString.Key.foregroundColor: UIColor.lightGray])
attributedTitle.append(NSMutableAttributedString(string: "Sign Up",
attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 16),
NSAttributedString.Key.foregroundColor: UIColor.mainBlueTint]))
$0.setAttributedTitle(attributedTitle, for: .normal)
$0.heightAnchor.constraint(equalToConstant: 32).isActive = true
$0.addTarget(self, action: #selector(handleShowSignUp), for: .touchUpInside)
}
NSMutableAttributedString안에 파라미터로 String과 어떻게 바꾸고싶은지를 attributes로 설정해주면되는데 이때 attribues는 key와 value로 이루어져있다