Instantly share code, notes, and snippets.
Created
July 9, 2015 17:06
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save DeFrenZ/75fd810da8e5e983221d to your computer and use it in GitHub Desktop.
UIButton subclass for having the image at different positions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// DZPositionedImageButton.swift | |
// Boppl | |
// | |
// Created by Davide De Franceschi on 18/05/2015. | |
// Copyright (c) 2015 Boppl. All rights reserved. | |
// | |
import UIKit | |
@IBDesignable | |
public class DZPositionedImageButton: UIButton { | |
public enum ImagePosition: Int { | |
case BottomLeft = 1, BottomCenter, BottomRight, CenterLeft, CenterRight = 6, TopLeft, TopCenter, TopRight | |
public enum HorizontalPosition { | |
case Left, Center, Right | |
} | |
public var horizontalPosition: HorizontalPosition { | |
switch self { | |
case .TopLeft, .CenterLeft, .BottomLeft: return .Left | |
case .TopCenter, .BottomCenter: return .Center | |
case .TopRight, .CenterRight, .BottomRight: return .Right | |
} | |
} | |
public enum VerticalPosition { | |
case Top, Center, Bottom | |
} | |
public var verticalPosition: VerticalPosition { | |
switch self { | |
case .TopLeft, .TopCenter, .TopRight: return .Top | |
case .CenterLeft, .CenterRight: return .Center | |
case .BottomLeft, .BottomCenter, .BottomRight: return .Bottom | |
} | |
} | |
} | |
public var imagePosition: ImagePosition = .CenterLeft { | |
didSet { updateEdgeInsets() } | |
} | |
@IBInspectable public var imagePositionInteger: Int { | |
get { return imagePosition.rawValue } | |
set { imagePosition = ImagePosition(rawValue: newValue) ?? .CenterLeft } | |
} | |
@IBInspectable public var contentGap: CGSize = .zeroSize { | |
didSet { updateEdgeInsets() } | |
} | |
private var _contentEdgeInsets: UIEdgeInsets = UIEdgeInsetsZero { | |
didSet { updateEdgeInsets() } | |
} | |
override public var contentEdgeInsets: UIEdgeInsets { | |
get { return super.contentEdgeInsets } | |
set { _contentEdgeInsets = newValue } | |
} | |
private func updateEdgeInsets() { | |
let initialEdgeInsets = contentEdgeInsets | |
if let image = currentImage, | |
label = titleLabel { | |
let imageSize = image.size | |
let labelSize = label.intrinsicContentSize() | |
let horizontalMultiplier = { () -> CGFloat in | |
switch self.imagePosition.horizontalPosition { | |
case .Left: return -0.5 | |
case .Center: return +0.0 | |
case .Right: return +0.5 | |
} | |
}() | |
let imageXOffset = +(labelSize.width * (horizontalMultiplier + 0.5) + contentGap.width * horizontalMultiplier) | |
let labelXOffset = -(imageSize.width * (horizontalMultiplier + 0.5) + contentGap.width * horizontalMultiplier) | |
let verticalMultiplier = { () -> CGFloat in | |
switch self.imagePosition.verticalPosition { | |
case .Top: return -0.5 | |
case .Center: return +0.0 | |
case .Bottom: return +0.5 | |
} | |
}() | |
let imageYOffset = +(labelSize.height * verticalMultiplier + contentGap.height * verticalMultiplier) | |
let labelYOffset = -(imageSize.height * verticalMultiplier + contentGap.height * verticalMultiplier) | |
super.imageEdgeInsets = UIEdgeInsetsMake(imageYOffset, imageXOffset, -imageYOffset, -imageXOffset) | |
super.titleEdgeInsets = UIEdgeInsetsMake(labelYOffset, labelXOffset, -labelYOffset, -labelXOffset) | |
let contentWidthInset = { () -> CGFloat in | |
switch self.imagePosition.horizontalPosition { | |
case .Center: return min(imageSize.width, labelSize.width) | |
default: return -self.contentGap.width | |
} | |
}() | |
let contentHeightInset = { () -> CGFloat in | |
switch self.imagePosition.verticalPosition { | |
case .Center: return 0 | |
default: return -(min(imageSize.height, labelSize.height) + self.contentGap.height) | |
} | |
}() | |
super.contentEdgeInsets = UIEdgeInsets(top: -contentHeightInset / 2, left: -contentWidthInset / 2, bottom: -contentHeightInset / 2, right: -contentWidthInset / 2) + _contentEdgeInsets | |
} | |
} | |
required public init(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
_contentEdgeInsets = contentEdgeInsets | |
} | |
} | |
public class DZLocalizedAttributedTitlePositionedImageButton: DZPositionedImageButton { | |
override public func awakeFromNib() { | |
super.awakeFromNib() | |
if let nibAttributedNormalTitle = attributedTitleForState(.Normal) { | |
setAttributedTitle(nibAttributedNormalTitle, forState: .Normal) | |
} | |
} | |
override public func setAttributedTitle(title: NSAttributedString!, forState state: UIControlState) { | |
super.setAttributedTitle(localizeAttributedStringByAttributesSections(title), forState: state) | |
updateEdgeInsets() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment