IBDesignable 사용한 커스텀 버튼, 스토리보드에서 설정하면 디자인이 바로 적용되는 것을 볼 수 있음.
- 모서리 Radius
- 이미지 + 텍스트 정렬 ( 가로배치 / 세로배치)
- 줄간격
- 자간
- Gradient Border / Background 컬러 적용
* 주의사항
- 소스에 폰트관련 내용은 커스텀 폰트 사용으로 소스를 첨부하지 않았다. 변경해서 사용할것
- https://limdongo.tistory.com/25 게시물의 UIViewExension 소스를 첨부하면 됨.
import UIKit
enum ImageFixedAlignedType: Int {
case NONE = 0
case CENTER_IMAGE_TEXT
case CENTER_TEXT_IMAGE
case EDGE_TEXT_IMAGE
}
@IBDesignable class IBCusomButton: UIButton {
@IBInspectable
public var fontStyleNumber: Int = 2{
didSet {
setup()
}
}
@IBInspectable
public var fontsize: CGFloat = 12.0 {
didSet {
setup()
}
}
// 줄간격 default : 21
@IBInspectable open var linesspacing:CGFloat = -1.0 {
didSet {
updateWithSpacing()
}
}
@IBInspectable open var letterSpacing:CGFloat = 1.0 {
didSet {
updateWithSpacing()
}
}
/*
@IBInspectable
public var fontColor: UIColor = UIColor.barbiePink {
didSet {
setup()
}
}
*/
@IBInspectable
public var alignTextSpacing: CGFloat = 0.0 {
didSet {
setup()
}
}
/// 이미지 + 텍스트 정렬 방식
@IBInspectable public var imagefixedInset: Int = 0{
didSet {
setup()
}
}
@IBInspectable
public var iconTintColor: UIColor = .black {
didSet {
setup()
}
}
/// 버튼 Radius 무조건 둥글게 (폰 해상도 반영 )
@IBInspectable
public var halfCornerRadius: Bool = false{
didSet {
if halfCornerRadius == true {
cornerRadius = self.frame.size.height/2.0
setup()
}
}
}
// var cornerRadius: CGFloat = 0.0 /// halfCornerRadius FALSE 일경우 적용
@IBInspectable
public var cornerRadius: CGFloat = 0.0{
didSet {
if halfCornerRadius == false {
setup()
}
}
}
@IBInspectable
public var borderWidth: CGFloat = 0.0{
didSet {
setup()
}
}
@IBInspectable
public var borderColor: UIColor = UIColor.clear {
didSet {
setup()
}
}
@IBInspectable
public var isGradientUseHighlight: Bool = false {
didSet {
// setup()
}
}
@IBInspectable
public var isGradientBorder: Bool = false {
didSet {
if isGradientBorder == false {
self.borderColor(width: borderWidth, borderColor: borderColor)
self.layer.cornerRadius = self.cornerRadius
} else {
setup()
}
}
}
@IBInspectable
public var isGradientBackground: Bool = false{
didSet {
setup()
}
}
@IBInspectable
public var bgOpacity: CGFloat = 1.0{
didSet {
setup()
}
}
var gradientStartPoint: CGPoint = CGPoint(x: 0.0, y: 0.0)
var gradientEndPoint: CGPoint = CGPoint(x: 1, y: 0)
var gradientBorderColors: [UIColor] = [UIColor.pinkishRed,
UIColor.barbiePink,
UIColor.marigold] {
didSet {
setup()
}
}
//[UIColor.reddishPink.cgColor, UIColor.mango.cgColor]
var gradientBGColors: [UIColor] = [UIColor.reddishPink, UIColor.mango] {
didSet {
setup()
}
}
var gradientHightlightedColors: [UIColor] = [UIColor.pinkishGrey,UIColor.brownishGreyTwo] {
didSet {
setup()
}
}
// 스토리보드에서 호출할 초기화 메서드
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
// 프로그래밍 방식으로 호출할 초기화 메서드
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
/*
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
*/
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setup()
}
override func layoutSubviews() {
super.layoutSubviews()
if self.frame.width == 0 || self.frame.height == 0 {
return
}
setup()
}
override var isHighlighted: Bool {
get {
// print(">>>> isHighlighted Get ")
return super.isHighlighted
} set {
if isGradientUseHighlight {
print(">>>> isHighlighted Set ")
setup()
}
super.isHighlighted = newValue
}
}
func setup() {
// setupImageRightfixedAligned()
/*
if let imageInsetType = ImageFixedAlignedType(rawValue: imagefixedInset) {
switch imageInsetType {
case .CENTER_IMAGE_TEXT, .CENTER_TEXT_IMAGE:
setupImagefixedCenterInset(aligned: imageInsetType)
case .EDGE_TEXT_IMAGE:
setupImageRightfixedAligned()
default: break
}
}*/
if imagefixedInset == ImageFixedAlignedType.CENTER_IMAGE_TEXT.rawValue {
setupImagefixedCenterInset(aligned: ImageFixedAlignedType.CENTER_IMAGE_TEXT)
} else if imagefixedInset == ImageFixedAlignedType.CENTER_TEXT_IMAGE.rawValue {
setupImagefixedCenterInset(aligned: ImageFixedAlignedType.CENTER_TEXT_IMAGE)
} else if imagefixedInset == ImageFixedAlignedType.EDGE_TEXT_IMAGE.rawValue {
setupImageRightfixedAligned()
}
if self.isGradientBorder == true {
self.removeLayer(layername: UIView.kLayerNameGradientBorder)
self.addBorderGradient(width: self.borderWidth,
colors: gradientBorderColors,
cornerRadius: self.cornerRadius)
} else {
self.borderColor(width: self.borderWidth, borderColor: self.borderColor)
}
if self.isGradientBackground == true {
self.removeLayer(layername: UIView.kLayerNameGradientBackground)
if isHighlighted == false || isGradientUseHighlight == false {
self.addBgGradient(colors: gradientBGColors, cornerRadius: self.cornerRadius, opacity: bgOpacity, shadow: false, startPoint: gradientStartPoint, endPoint: gradientEndPoint)
} else {
self.addBgGradient(colors: gradientHightlightedColors, cornerRadius: self.cornerRadius, opacity: bgOpacity, shadow: false, startPoint: gradientStartPoint, endPoint: gradientEndPoint)
}
} else {
self.removeLayer(layername: UIView.kLayerNameGradientBackground)
if let bgColor = self.backgroundColor {
self.backgroundColor = bgColor.withAlphaComponent(bgOpacity)
}
}
if let fontStyle = FontStyleNumber.init(rawValue: fontStyleNumber) {
let sytlefont = UIFont.notoSansFont(forFont: fontStyle.fontName, size: fontsize)
self.titleLabel?.font = sytlefont
// self.setTitleColor(self.fontColor, for: .normal)
// self.titleLabel?.textAlignment = .center
self.titleLabel?.adjustsFontForContentSizeCategory = true
// self.titleLabel?.adjustsFontSizeToFitWidth = true
}
if alignTextSpacing > 0.0, self.isHidden == false {
alignTextBelow(spacing: alignTextSpacing)
}
if self.imageView != nil {
if let imageView = self.imageView, let image = imageView.image {
if self.iconTintColor != UIColor.black {
self.imageView?.image = image.withRenderingMode(.alwaysTemplate)
self.tintColor = iconTintColor
}
}
}
//self.clipsToBounds = true
//autoresizingMask = [.flexibleWidth, .flexibleHeight]
//contentHorizontalAlignment = UIControl.ContentHorizontalAlignment.center
//content 사이즈 변경 사항이 있을 경우 호출(다른 레이아웃 사이즈 조정??)
invalidateIntrinsicContentSize()
}
/*
- titleText Left and image Right Aligned
속성 : 버튼 기본 설정 상태
| title 😄 |
*/
func setupImageRightfixedAligned() {
self.semanticContentAttribute = .unspecified
// self.contentHorizontalAlignment = .left
self.imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - 25), bottom: 5, right: 5)
self.titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: (imageView?.frame.width)!)//+15)
}
/* 버튼 이미지, 텍스트 중앙 정렬
- image Left and titleText Right Center Aligned
속성 : semanticContentAttribute = .unspecified
| 😄 korea |
| 😄 usa |
| 😄 japan |
- titleText Left and image Right Center Aligned
속성 : semanticContentAttribute = .forceRightToLeft
| korea 😄 |
| usa 😄 |
| japan 😄 |
*/
func setupImagefixedCenterInset(aligned type: ImageFixedAlignedType) {
guard let title = self.titleLabel else { return }
title.sizeToFit()
let viewWidth = self.frame.width / 2.0
var imageWidth = self.imageView?.frame.width ?? 0.0
if imageWidth > 0.0 {
imageWidth = imageWidth / 2.0
}
let titleWidth = title.frame.width / 2.0
switch type {
case .CENTER_TEXT_IMAGE:
self.semanticContentAttribute = .forceRightToLeft
self.contentHorizontalAlignment = .right
self.titleEdgeInsets.right = viewWidth - titleWidth - imageWidth
self.imageEdgeInsets.right = (viewWidth/2.0) - imageWidth
case .CENTER_IMAGE_TEXT:
self.semanticContentAttribute = .unspecified
self.contentHorizontalAlignment = .left
self.titleEdgeInsets.left = viewWidth - titleWidth - imageWidth
self.imageEdgeInsets.left = (viewWidth/2.0) - imageWidth
default: break
}
}
/*
이미지(상단) / 텍스트(하단) 배치
*/
func alignTextBelow(spacing: CGFloat) {
//let spacing: CGFloat = 6.0
if self.imageView != nil {
if let imageView = self.imageView {
let imageSize = imageView.frame.size
self.titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageSize.width, bottom: -(imageSize.height + spacing), right: 0)
let titleSize = self.titleLabel!.frame.size
self.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + spacing), left: 0, bottom: 0, right: -titleSize.width)
}
}
}
func updateWithSpacing() {
guard let lable = self.titleLabel, let attributedText = lable.attributedText else {
return
}
let attributedString = NSMutableAttributedString(string: lable.text ?? "")// : NSMutableAttributedString(attributedString: lable.attributedText ?? "")
// 자간 간격 설정
attributedString.addAttribute(NSAttributedString.Key.kern, value: self.letterSpacing, range: NSRange(location: 0, length: attributedString.length))
// 줄간격 (default - 21)
if linesspacing > 0 {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.minimumLineHeight = linesspacing
paragraphStyle.maximumLineHeight = linesspacing
paragraphStyle.alignment = lable.textAlignment
attributedString.addAttribute(NSAttributedString.Key.font, value: lable.font!, range: NSRange(location: 0, length: attributedString.length))
attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedString.length))
}
super.titleLabel?.attributedText = attributedString
}
}
'Swift > UIButton' 카테고리의 다른 글
[SWIFT] UIButton 아이콘 하단 텍스트 표시 (0) | 2023.11.06 |
---|---|
[SWIFT]UIButton Action 함수 호출 하기 (0) | 2023.06.09 |
[SWIFT]백그라운드 이미지 사용 안하고 버튼 이미지 레이어에 백그라운드 컬러 적용 (0) | 2023.06.09 |