ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [UIKit] UIButton의 Image, Title 크기 조절하기
    iOS/UIKit 2021. 12. 16. 02:00

    안녕하세요. miniOS입니다! TIL은 평어체를 사용하여 작성하겠습니다.


    UI를 Code로만 구현해보는 연습을 하기 위해서, 위와 같은 화면을 따라서 만들어 보았다.

    오른쪽 상단의 버튼들은 Image만을 갖고있는 버튼이고,

    중앙 하단의 버튼들은 Image와 Title을 갖고있는 버튼이다.

    ImageSize

    @available(iOS 13.0, *)

    iOS 13 버전부터 UIImage.SymbolConfiguration 클래스를 사용할 수 있게 되었다.

    설명을 보면, image의 font, size, style, weight와 같은 속성들에 대한 정보를 포함한 객체라고 나와있다.

    위의 초기화 함수중에 하나로 크기를 조절할 수 있다.

    별다른 프로퍼티가 없는것으로 보아, 초기화를 통해서만 설정을 해줄 수 있는것으로 보인다.


    pointSize

    위의 초기화 함수에서 보이는 pointSize가 무엇을 의미하는지 궁금했었다.

    Developer Documentation에서 찾아본 결과 UIFont에서 font의 크기와 같은 의미인것같다.


    이제, 생성된 Configuration을 적용해 주면 되는데

    iOS 15.0에서 새로 등장한 UIButton.Configurateion을 통해서 적용해줄 수도 있고,

    그 이전 버전과 동일하게 적용해줄 수도 있다.

    아래 코드를 참고해서 적용하면 되겠다.

    let pointSize: CGFloat = 10
    let imageConfig = UIImage.SymbolConfiguration(pointSize: pointSize)
    if #available(iOS 15.0, *) {
        var config = UIButton.Configuration.plain()
        config.preferredSymbolConfigurationForImage = imageConfig
        button.configuration = config
    } else {
        button.setPreferredSymbolConfiguration(config, forImageIn: .normal)
    }

    참고로 SFSymbolUIImage(systemName: )으로 생성된 이미지의 경우에 해당하는지는 모르겠지만

    기본적인 pointSize는 17이다.

    TitleSize

    왜인지 모르게, font를 직접 지정해주는 코드가 동작하지 않았다.

    button.titleLabel?.font = .systemFont(ofSize: <pointSize>)

    그래서 다른 UIKit 오브젝트들의 font를 설정해줬던 방법대로 적용하기로 했다.

    NSAttributedString

    이 `NSAttributedString`은 아주 효과가 확실해서, 다른 방법으로 적용이 잘 안될 때 자주 사용하는 방법이다.

    visual style, hyperlink, accessibility data 등등 string과 관련된 특성들을 부분적으로 또는 전체에 적용가능한 String이라고 소개되어있다.

    attributes를 [Dict]? 타입으로 초기화해주면 되는데, `Key`값에는 정말 여러가지가 있다.

    https://developer.apple.com/documentation/foundation/nsattributedstring/key

     

    Apple Developer Documentation

     

    developer.apple.com

    간단하게 size만 적용해보자면 아래와 같다.

        let attribute = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: <pointSize>)]
        let attributedTitle = NSAttributedString(string: <titleText>, attributes: attribute)
        button.setAttributedTitle(attributedTitle, for: .normal)

    Custom Button에서 적용

    다시 연습하고있던 화면으로 돌아와서, 중앙 하단에 있는 버튼들을 Custom Button Class를 생성해 적용해보았다.

    class KakaoButton: UIButton {
        let pointSize: CGFloat = 13
        let imagePadding: CGFloat = 15
    
        override init(frame: CGRect) {
            super.init(frame: frame)
    
            tintColor = .white
    
            let imageConfig = UIImage.SymbolConfiguration(pointSize: pointSize)
            if #available(iOS 15.0, *) {
                var config = UIButton.Configuration.plain()
                config.imagePadding = imagePadding
                config.imagePlacement = .top
                
                config.preferredSymbolConfigurationForImage = imageConfig
                configuration = config
            } else {
                // imageSize == fontSize 일때 가능
                guard let image = self.imageView?.image else { return }
                guard let titleLabel = self.titleLabel else { return }
                guard let titleText = titleLabel.text else { return }
                let titleSize = titleText.size(withAttributes: [
                    NSAttributedString.Key.font: titleLabel.font as Any
                ])
                titleEdgeInsets = UIEdgeInsets(top: imagePadding, left: -image.size.width, bottom: -image.size.height, right: 0)
                imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + imagePadding), left: 0, bottom: 0, right: -titleSize.width)
                
                setPreferredSymbolConfiguration(imageConfig, forImageIn: .normal)
            }
    
        }
    
        override func setTitle(_ title: String?, for state: UIControl.State) {
            super.setTitle(title, for: state)
            guard let text = title else { return }
            let attribute = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: pointSize)]
            let attributedTitle = NSAttributedString(string: text, attributes: attribute)
            self.setAttributedTitle(attributedTitle, for: .normal)
        }
    
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }

    댓글

Designed by Tistory.