viewDidLoad
까지 가는 길도 멀어진다..UILabel
, UIButton
, UITextField
을 잘 구현했는데,UIImagView
에서 많은 고난과 역경이 있었다..// CustomImageView.swift
class CustomImageView: UIImageView {
override init(frame: CGRect) {
super.init(frame: frame)
setConfigure()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setConfigure() {
backgroundColor = .yellow
layer.borderColor = UIColor.black.cgColor
layer.borderWidth = 1
clipsToBounds = true
// 문제의 코드 - 이미지뷰의 cornerRadius를 조절해서 완벽한 원을 만든다
layer.cornerRadius = frame.width / 2
}
}
class CircleImageViewController: UIViewController {
// ImageView는 다른 클래스와 다르게 생성 시 필수로 매개변수를 입력해주어야 한다
// 일단 0, 0, 0, 0으로 넣어줬다
let movieImage = CustomImageView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
movieImage.image = UIImage(named: "부산행")
view.addSubview(movieImage)
movieImage.snp.makeConstraints { make in
make.top.equalTo(view).offset(80)
make.centerX.equalTo(view)
// layout size는 200으로 고정한다
make.size.equalTo(200)
}
}
}
분명 layer.cornerRadius = frame.width / 2
를
이미지뷰를 디자인하는 함수에 작성해주었는데
cornerRadius가 전혀 바뀌지 않는다.
완벽한 정사각형을 보여준다
frame.width
를 사용한다.CGRect()
값이let movieImage = CustomImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
생각해보면, 화면에 보이는 이미지의 크기는
SnapKit을 이용한 레이아웃을 잡을 때 결정되는 듯 하다.
즉, 화면에 보이는 객체의 size는 200인데,
cornerRadius에 주는 값은 100/2 = 50 이기 때문에
2의 그림처럼 애매하게 굴곡진 모양이 나온다고 생각했다
그래서 frame에 넣어주는 width, height
값과
layout에서 size
를 동일하게 만들었다
let movieImage = CustomImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
movieImage.snp.makeConstraints { make in
~~
make.size.equalTo(200)
}
하다보니 생각난 점은,
애초에 CGRect()
값까지 넣어주면서 객체의 크기를 잡아주는데,
이러면 레이아웃에서 굳이 size를 지정해 줄 필요가 없다고 생각했다
따라서 레이아웃에서 설정해줄 값을 CGRect
에 미리 넣어주면,
코드의 중복을 피할 수 있다 라고 생각..했다...
let movieImage = CustomImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
movieImage.snp.makeConstraints { make in
~~
// make.size.equalTo(200)
}
군번줄같이 생긴 이미지가 나온다
어쨌든 cornerRadius 값은 적용된 걸 확인할 수 있다
하지만 CGRect에 넣어준 대로 사이즈가 고정되지 않았다
기존 이미지의 크기에 맞춰서 레이아웃이 잡혔다고 볼 수 있다
4에서 CGRect와 상관없이 이미지의 크기에 따라 레이아웃이 잡힌 걸 확인할 수 있었다
그럼 이미지가 없으면 어떻게 될까
이미지 뷰를 생성할 때 넣어주는 frame 값과
나중에 레이아웃에서 잡아주는 이미지의 size 값을
동일하게 해두어야, 완벽한 원 모양의 이미지를 얻을 수 있다
처음에 넣어주는 CGRect로 디폴트 사이즈를 잡아준다고 생각하자
코드적으로 크게 의미가 없는 부분이지만, 뷰의 계층구조상 필수적인 코드이다
하위 뷰의 레이아웃을 잡아주는 메서드이다
깔끔한 원으로 확인 가능
class CircleImageViewController: UIViewController {
// frame 값으로 zero 를 넣어준다 -> 어차피 사용하지 않는 값
let movieImage = CustomImageView(frame: .zero)
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
movieImage.image = UIImage(named: "부산행")
view.addSubview(movieImage)
movieImage.snp.makeConstraints { make in
make.top.equalTo(view).offset(80)
make.centerX.equalTo(view)
make.size.equalTo(200)
print("현재 함수 makeConstraints, frame.width : ", movieImage.frame.width)
}
}
}
class CustomImageView: UIImageView {
override init(frame: CGRect) {
super.init(frame: frame)
setConfigure()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setConfigure() {
backgroundColor = .yellow
layer.borderColor = UIColor.black.cgColor
layer.borderWidth = 1
clipsToBounds = true
print("현재 함수 setConfigure, frame.width : ", frame.width)
// 아예 코드를 옮겨준다 (여기서 실행할 필요가 없다)
// layer.cornerRadius = frame.width / 2
}
override func layoutSubviews() {
super.layoutSubviews()
print("현재 함수 layoutSubivews, frame.width : ", frame.width)
// 레이아웃을 잡고난 이후에 frame 값이 바뀔 가능성이 있기 때문에
// 여기서 cornerRadius 값을 지정해준다
layer.cornerRadius = frame.width / 2
}
}