Каков наилучший способ автоматического изменения размера UIButton на основе его содержимого, в основном его заголовка и изображения? - PullRequest
0 голосов
/ 10 июня 2019

Я написал приведенный ниже код для генерации пользовательского UIButton, который я намерен использовать в разных местах в своих приложениях:

import UIKit

import ChameleonFramework

class CustomButton: UIButton {

    override init(frame: CGRect) {

        super.init(frame: frame)

    }

    required init?(coder aDecoder: NSCoder) {

        super.init(coder: aDecoder)

    }

    convenience init(buttonTitleTexForNormalState titleForNormalState: String, buttonTitleTextColourForNormalState normalTextColour: UIColor, buttonTitleTextColourForHighlightedState highlightedTextColour: UIColor, buttonTitleFontType fontType: String, buttonTitleFontSize fontSize: CGFloat, buttonBackgroundHexColourCode hexColour: String, buttonFrameCornerRadius cornerRadius: CGFloat, buttonFrameBorderWidth borderWidth: CGFloat, buttonFrameBorderColour borderColour: String, buttonBackgroundTransperancyAlphaValue transperancy: CGFloat, buttonTagNumber tagValue: Int, buttonTarget: Any?, buttonSelector: Selector, buttonImageForNormalState normalButtonImage: String) {

        self.init()

        setupButtonEssentials(buttonTitleTexForNormalState: titleForNormalState, buttonTitleTextColourForNormalState: normalTextColour, buttonTitleTextColourForHighlightedState: highlightedTextColour, buttonTitleFontType: fontType, buttonTitleFontSize: fontSize, buttonBackgroundHexColourCode: hexColour, buttonFrameCornerRadius: cornerRadius, buttonFrameBorderWidth: borderWidth, buttonFrameBorderColour: borderColour, buttonBackgroundTransperancyAlphaValue: transperancy, buttonTagNumber: tagValue, buttonTarget: buttonTarget, buttonSelector: buttonSelector, buttonImageForNormalState: normalButtonImage)

    }

    func setupButtonEssentials(buttonTitleTexForNormalState titleForNormalState: String, buttonTitleTextColourForNormalState normalTextColour: UIColor, buttonTitleTextColourForHighlightedState highlightedTextColour: UIColor, buttonTitleFontType fontType: String, buttonTitleFontSize fontSize: CGFloat, buttonBackgroundHexColourCode hexColour: String, buttonFrameCornerRadius cornerRadius: CGFloat, buttonFrameBorderWidth borderWidth: CGFloat, buttonFrameBorderColour borderColour: String, buttonBackgroundTransperancyAlphaValue transperancy: CGFloat, buttonTagNumber tagValue: Int, buttonTarget: Any?, buttonSelector: Selector, buttonImageForNormalState normalButtonImage: String) {

        setTitleColor(normalTextColour, for: .normal)

        setTitleColor(highlightedTextColour, for: .highlighted)

        titleLabel?.font = UIFont(name: fontType, size: fontSize)

        setTitle(titleForNormalState, for: .normal)

        backgroundColor = UIColor(hexString: hexColour)

        layer.cornerRadius = cornerRadius

        layer.borderWidth =  borderWidth

        layer.borderColor = UIColor(hexString: borderColour)?.cgColor

        showsTouchWhenHighlighted = true

        alpha = transperancy

        contentHorizontalAlignment = .center

        self.tag = tagValue

        addTarget(target, action: buttonSelector, for: .touchUpInside)

        if let buttonImage = UIImage(named: normalButtonImage) {

            setImage(buttonImage.withRenderingMode(.alwaysOriginal), for: .normal)

            contentMode = .scaleAspectFit

        }

        setShadow()

        translatesAutoresizingMaskIntoConstraints = false

    }

    private func setShadow() {

        layer.shadowColor = UIColor.black.cgColor

        layer.shadowOffset = CGSize(width: 0.0, height: 6.0)

        layer.shadowRadius = 8

        layer.shadowOpacity = 0.5

        clipsToBounds = true

        layer.masksToBounds = false

    }

    func shake() {

        let shake = CABasicAnimation(keyPath: "position")

        shake.duration = 0.1

        shake.repeatCount = 2

        shake.autoreverses = true

        let fromPoint = CGPoint(x: center.x-8, y: center.y)

        let fromValue = NSValue(cgPoint: fromPoint)

        let toPoint = CGPoint(x: center.x+8, y: center.y)

        let toValue = NSValue(cgPoint: toPoint)

        shake.fromValue = fromValue

        shake.toValue = toValue

        layer.add(shake, forKey: "position")

    }

}

А приведенный ниже код иллюстрирует пример того, где я создалэкземпляр из пользовательского класса UIButton (как показано выше) внутри ViewController:

import UIKit

import ChameleonFramework

class MainScreen: UIViewController, UINavigationBarDelegate {

    var newFileButton = CustomButton(buttonTitleTexForNormalState: "New...", buttonTitleTextColourForNormalState: .black, buttonTitleTextColourForHighlightedState: .blue, buttonTitleFontType: "Apple SD Gothic Neo", buttonTitleFontSize: 17, buttonBackgroundHexColourCode: "#B24B32", buttonFrameCornerRadius: 25, buttonFrameBorderWidth: 2, buttonFrameBorderColour: "#7AFFD2", buttonBackgroundTransperancyAlphaValue: 0.75, buttonTagNumber: 1, buttonTarget: self, buttonSelector: #selector(buttonPressed(sender:)), buttonImageForNormalState: "New File")

    override func viewDidLayoutSubviews() {

        super.viewDidLayoutSubviews()

        print("viewDidLayoutSubviews")

        view.addSubview(newFileButton)

        newFileButton.frame.size.width = 140

        newFileButton.frame.size.height = 100

    }

    @objc func buttonPressed(sender : UIButton) {

        if sender.tag == 1 {

            newFileButton.shake()

            guard let nextViewControllerToGoTo = storyboard?.instantiateViewController(withIdentifier: "NewFileButtonPressedTabController") else {

                print("NewFileButtonPressedTabController could not be presented")

                return

            }

            present(nextViewControllerToGoTo, animated: true, completion: nil)         

    }

}

Однако, как видно из приведенного выше кода, я в конечном итоге определил размер пользовательского UIButton с точки зрения егоширина и высота вручную.

Интересно, есть ли способ для Xcode определить оптимальную ширину и высоту для каждой пользовательской кнопки UIB на основе его содержимого, главным образом его заголовка и изображения?

PSЯ пытался использовать intrinsicContent, однако у меня не получилось.Любые предложения приветствуются.

Спасибо, Шади.

1 Ответ

0 голосов
/ 10 июня 2019

Удалите код, который устанавливает newFileButton.frame.size.width и .height, и он должен принимать размер содержимого любых заголовков / изображений, которые вы добавляете к нему - но только как минимум. Если вы хотите, чтобы он был больше, просто установите вставки содержимого (вроде как заполнение вокруг содержимого).

В классе вашей кнопки:

self.contentEdgeInsets = UIEdgeInsets(top: 10, left: 30, bottom: 10, right: 20)
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: -20, bottom: 0, right: 0)
...