Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Clean Code
- SWIFT
- map
- combine
- swift documentation
- Refactoring
- 스위프트
- 리펙토링
- 애니메이션
- collectionview
- UITextView
- ios
- RxCocoa
- HIG
- 리팩토링
- MVVM
- uiscrollview
- Xcode
- 리펙터링
- 클린 코드
- uitableview
- clean architecture
- ribs
- swiftUI
- UICollectionView
- Human interface guide
- Protocol
- tableView
- Observable
- rxswift
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] UIButton의 imageView 크기 조절 방법 (imageView, titleLabel) 본문
iOS 응용 (swift)
[iOS - swift] UIButton의 imageView 크기 조절 방법 (imageView, titleLabel)
jake-kim 2023. 4. 4. 01:33
UIButton의 imageView, titleLabel
- UIButton에는 내부적으로 UIImageView와 UILabel이 존재
- 아래처럼 UIButton하나만 사용하면 버튼안에 이미지와 텍스트 삽입이 가능
import UIKit
class ViewController: UIViewController {
private let button: UIButton = {
let button = UIButton()
button.setTitle("button", for: .normal)
button.setTitleColor(.systemBlue, for: .normal)
button.setTitleColor(.blue, for: .highlighted)
button.addTarget(self, action: #selector(tapButton), for: .touchUpInside)
button.backgroundColor = .lightGray
button.layer.cornerRadius = 12
button.clipsToBounds = true
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.black.cgColor
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(button)
NSLayoutConstraint.activate([
button.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16),
button.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16),
])
button.setImage(UIImage(named: "img"), for: .normal)
}
@objc
private func tapButton() {
print("tap!")
}
}
- UIButton안에 있는 imageView의 크기를 설정하는 방법?
- 1번) button.imageView, button.titleLabel 각각 인스턴스를 얻어서 autolayout을 하는 방법
button.imageView?.translatesAutoresizingMaskIntoConstraints = false
button.titleLabel?.translatesAutoresizingMaskIntoConstraints = false
...
- 위처럼하면 코드가 길어지게되므로 다른 방법 사용
- imageEdgeInsets 프로퍼티를 활용하여 구현이 가능
imageEdgeInsets 개념
- UIButton에는 3가지의 inset 옵션이 존재
- imageEdgeInsets
- titleEdgeInsets
- contentEdgeInsets
(3가지 구체적인 개념은 이전 포스팅 글 참고)
- imageEdgeInsets에서 left에 10을 주면 이미지가 왼쪽에 10만큼 margin이 생기게 되어 오른쪽으로 이동
button.imageEdgeInsets = .init(top: 0, left: 10, bottom: 0, right: 0)
- inset의 핵심
- top, left, bottom, right 모두 button과의 간격이 기준임
- titleLabel과의 기준이 아님을 주의
ex) 만약 right: 10을 주면 아무 변동이 없음
(이미 titleLabel의 길이만큼 떨어져 있으므로 이 길이보다 작은값을 주게되면 무시됨)
button.imageEdgeInsets = .init(top: 0, left: 0, bottom: 0, right: 10)
- titlaLabel의 길이보다 조금 더 크게 주게되면 적용됨
ex) 이미지와 titlaLabel 간의 간격을 5로 하고싶은 경우?
- layoutSubview 에서 titleLabel의 크기가 정해질때 길이를 구해서 이 값에 + 5를 button.inageEdgeInsets의 right에 주면 해결
- iamgeEdgeInsets.right값이 증가하면 오른쪽에 있는 label도 오른쪽으로부터 +5가 되므로 left값으로 채워줘야함
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let titleLabelWidth = button.titleLabel?.frame.width ?? 0
guard titleLabelWidth > 0 else { return }
let imageRightSpacing = 5.0
button.imageEdgeInsets = .init(top: 0, left: 0, bottom: 0, right: titleLabelWidth + imageRightSpacing)
button.titleEdgeInsets = .init(top: 0, left: imageRightSpacing, bottom: 0, right: 0)
}
이미지 사이즈 고정하기
- 요구사항
- 버튼 내부의 콘텐츠(imageView, titleLabel)의 간격을 5로 설정
- imageView와 titleLabel사이의 간격을 16으로 설정
- 이미지 사이즈 50 x 50으로 설정
- 구현 방법
- 내부 콘텐츠가 고정된 크기라고 가정하면, 버튼의 크기를 고정하고나서 내부 크기를 설정해주는 방향으로 구현
- 구현 목적은 autolayout없이 간편하게 설정하는 것
1. 버튼 내부의 콘텐츠(imageView, titleLabel)의 간격을 5로 설정
- contentEdgeInsets 사용 (이 값을 사용하면 뷰가 줄어드는게 아닌 커지는 쪽으로 content가 증가)
button.contentEdgeInsets = .init(top: 5, left: 5, bottom: 5, right: 5)
2. imageView와 titleLabel사이의 간격을 16으로 설정
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
setSpacingImageViewAndTitleLabel(spacing: 16)
}
private func setSpacingImageViewAndTitleLabel(spacing: CGFloat) {
let titleLabelWidth = button.titleLabel?.frame.width ?? 0
guard titleLabelWidth > 0 else { return }
button.imageEdgeInsets = .init(top: 0, left: 0, bottom: 0, right: titleLabelWidth + spacing)
button.titleEdgeInsets = .init(top: 0, left: spacing, bottom: 0, right: 0)
}
3. 이미지 사이즈 50 x 50으로 설정
- 지금은 이미지 고유의 사이즈만큼 imageView가 커진 상태
- 이미지의 크기를 줄이기 위해서 UIButton의 크기를 고정시켜버리면, 안쪽 뷰의 크기가 동적으로 변경되는 것에 맞추어서 UIButton의 크기가 동적으로 변하지 않으므로 UIButton의 크기를 고정시키는 방법은 지양
- CGContext를 사용하여 UIImage의 크기를 줄여서 사용하면 해결
(resize 메소드 의미는 이전 포스팅 글 참고)
extension UIImage {
func resize(targetSize: CGSize) -> UIImage? {
let newRect = CGRect(x: 0, y: 0, width: targetSize.width, height: targetSize.height).integral
UIGraphicsBeginImageContextWithOptions(newRect.size, true, 0)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
context.interpolationQuality = .high
draw(in: newRect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
private let button: UIButton = {
let button = UIButton()
// 이미지 크기 줄여서 사용
let imageSize = CGSize(width: 100, height: 100)
let resizedImage = UIImage(named: "img")?.resize(targetSize: imageSize)
button.imageView?.contentMode = .scaleToFill
...
return button
}()
주의) 이미지 크기를 줄일 때 scale을 잘못 입력하면 이미지가 흐려보이니 주의
- 이미지 리사이징 관련 개념은 이전 포스팅 글 참고
그래픽스를 사용할때 scale을 현재 화면 크기 기준으로 잡은 경우 | 그래픽스를 사용할때 scale을 이미지 크기의 기준으로 잡은 경우 |
* 전체 코드: https://github.com/JK0369/ExUIImage_imageView
'iOS 응용 (swift)' 카테고리의 다른 글
Comments