簡體   English   中英

Swift iOS-如何實現具有不同字體大小的多行SegmentedControl

[英]Swift iOS -How to Achieve Multi line SegmentedControl with different Font Sizes

我有2行使用SegmentedControl:

// AppDelegate  
UILabel.appearanceWhenContainedInInstancesOfClasses([UISegmentedControl.self]).numberOfLines = 0

在此輸入圖像描述

問題是線條字體的大小完全相同。 我需要為每一行更改titleTextAttributes,以便第二行小於第一行。

我知道我可以在兩行中使用它:

segmentedControl.setTitleTextAttributes([NSAttributedStringKey.font : UIFont.systemFont(ofSize: 17))

我怎樣才能做到這一點?

// The SegmentedControl
let segmentedControl: UISegmentedControl = {
    let segmentedControl = UISegmentedControl(items: ["Pizza\n123.1K", "Turkey Burgers\n456.2M", "Gingerale\n789.3B"])
    segmentedControl.translatesAutoresizingMaskIntoConstraints = false
    segmentedControl.tintColor = UIColor.orange
    segmentedControl.backgroundColor = .white
    segmentedControl.isHighlighted = true
    segmentedControl.addTarget(self, action: #selector(selectedIndex(_:)), for: .valueChanged)
    return segmentedControl
}()

您將需要通過繼承UIControl來創建自定義控件。 這是一個簡單的例子:

CustomSegmentedControl.swift

import UIKit
import CoreImage

public class CustomSegmentedControl: UIControl {

    public var borderWidth: CGFloat = 1.0
    public var selectedSegementIndex = 0 {
        didSet {
            self.styleButtons()
        }
    }

    public var numberOfSegments: Int {
        return self.segments.count
    }

    private var buttons: [UIButton] = []
    private var stackView = UIStackView(frame: CGRect.zero)
    private var stackBackground = UIView(frame: CGRect.zero)
    private var segments: [NSAttributedString] = [] {
        didSet {
            for subview in self.stackView.arrangedSubviews {
                subview.removeFromSuperview()
            }
            self.buttons = []
            for i in 0..<segments.count {
                let segment = segments[i]
                self.createAndAddSegmentButton(title: segment)
            }
            self.styleButtons()
        }
    }

    override public init(frame: CGRect) {
        super.init(frame: frame)
        self.setup()
    }

    public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setup()
    }

    private func setup() {

        self.addSubview(stackBackground)
        self.stackBackground.constrainToBounds(of: self)
        self.addSubview(stackView)
        self.stackView.constrainToBounds(of: self)
        self.stackView.axis = .horizontal
        self.stackView.distribution = .fillEqually
        self.stackView.spacing = borderWidth

        self.layer.cornerRadius = 5.0
        self.layer.borderWidth = borderWidth
        self.clipsToBounds = true
        self.stackBackground.backgroundColor = tintColor
    }

    private func createAndAddSegmentButton(title: NSAttributedString) {
        let button = createSegmentButton(title: title)
        self.buttons.append(button)
        self.stackView.addArrangedSubview(button)
    }

    private func createSegmentButton(title: NSAttributedString) -> UIButton {
        let button = UIButton(frame: CGRect.zero)
        button.titleLabel?.numberOfLines = 0
        button.titleLabel?.textAlignment = .center
        button.setAttributedTitle(title, for: .normal)
        button.addTarget(self, action: #selector(self.actSelected(button:)), for: .touchUpInside)
        return button
    }

    override public var tintColor: UIColor! {
        willSet {
            self.layer.borderColor = newValue.cgColor
            self.stackBackground.backgroundColor = newValue
        }
    }

    public func setSegments(_ segments: [NSAttributedString]) {
        self.segments = segments
    }

    @objc private func actSelected(button: UIButton) {
        guard let index = self.buttons.index(of: button) else {
            print("invalid selection should never happen, would want to handle better than this")
            return
        }
        self.selectedSegementIndex = index
        self.sendActions(for: .valueChanged)
    }

    private func styleButtons() {
        for i in 0..<self.buttons.count {
            let button = self.buttons[i]
            if i == selectedSegementIndex {
                button.backgroundColor = self.tintColor
                button.titleLabel?.textColor = self.backgroundColor ?? .white
            } else {
                button.backgroundColor = self.backgroundColor
                button.titleLabel?.textColor = self.tintColor
            }
        }
    }
}

extension UIView {
    func constrainToBounds(of view: UIView) {
        self.translatesAutoresizingMaskIntoConstraints = false
        let attrs: [NSLayoutAttribute] = [.leading, .top, .trailing, .bottom]
        let constraints = attrs.map { (attr) -> NSLayoutConstraint in
            return NSLayoutConstraint(item: self,
                                      attribute: attr,
                                      relatedBy: .equal,
                                      toItem: view,
                                      attribute: attr,
                                      multiplier: 1.0,
                                      constant: 0)
        }
        NSLayoutConstraint.activate(constraints)
    }
}

ViewController.swift

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var customSegment: CustomSegmentedControl!
    private var segments: [NSAttributedString] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.customSegment.backgroundColor = .white
        self.customSegment.tintColor = .orange

        let pizza = createText(title: "Pizza", subTitle: "123K")
        let turkey = createText(title: "Turkey Burgers", subTitle: "456.2M")
        let gingerAle = createText(title: "Gingerale", subTitle: "789.3B")
        self.segments = [pizza, turkey, gingerAle]
        self.customSegment.setSegments(self.segments)

        self.customSegment.addTarget(self, action: #selector(self.segmentSelectionChanged(control:)), for: .valueChanged)
    }

    @objc private func segmentSelectionChanged(control: CustomSegmentedControl) {
        let segment = self.segments[control.selectedSegementIndex]
        print("selected segment = \(segment.string)")
    }

    func createText(title: String, subTitle: String) -> NSAttributedString {
        let titleStr = NSMutableAttributedString(string: "\(title)\n", attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 16)])
        let subStr = NSAttributedString(string: subTitle, attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 10)])
        titleStr.append(subStr)
        return titleStr
    }

}

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM