Александр Зимин
TRANSCRIPT
iOS Developer UI Engineer
CocoaHeadsRussia
macOS Developer Co-Founder Организатор
Маркетинг, Дизайн, Аналитика, …
extension UIColor { enum ColorType: String { case gray = "8C8C8C" case darkGray = "6C6C6C" }
convenience init(_ colorType: ColorType) { self.init(hexString: colorType.rawValue) } }
extension UIColor { enum ComponentType { case navigationBar case separator
var colorType: ColorType { switch self { case .navigationBar: return .gray case .separator: return .darkGray } } }
convenience init(componentType: ComponentType) { self.init(componentType.colorType) } }
extension UIColor { enum ComponentType { case navigationBar case separator
var colorType: ColorType { switch self { case .navigationBar: return .gray case .separator: return .darkGray } } }
convenience init(componentType: ComponentType) { self.init(componentType.colorType) } }
Не может содержать HEX строк!
extension UIFont { enum FontType { case gothamProMedium(size: CGFloat) case gothamPro(size: CGFloat) }
convenience init(_ fontType: FontType) { switch fontType { case let .gothamProMedium(size): self.init(name: "GothamPro-Medium", size: size)! case let .gothamPro(size): self.init(name: "GothamPro", size: size)! } } }
viewDidLoad customViewDidLoad
• При вызове viewDidLoad вызывается customViewDidLoad • При вызове customViewDidLoad вызывается viewDidLoad
private var swizzleTextValue: Void = { swizzleMethods(objectClass: UILabel.self, originalSelector: #selector(setter: UILabel.text), swizzledSelector: #selector(UILabel.setStaticText(_:))) }()
extension UILabel { open override class func initialize() { _ = swizzleTextValue } @objc fileprivate func setStaticText(_ text: String?) { setStaticText(text) // You actions } }
private var swizzleTextValue: Void = { swizzleMethods(objectClass: UILabel.self, originalSelector: #selector(setter: UILabel.text), swizzledSelector: #selector(UILabel.setStaticText(_:))) }()
extension UILabel { open override class func initialize() { _ = swizzleTextValue } @objc fileprivate func setStaticText(_ text: String?) { setStaticText(text) // You actions } }
private var swizzleTextValue: Void = { swizzleMethods(objectClass: UILabel.self, originalSelector: #selector(setter: UILabel.text), swizzledSelector: #selector(UILabel.setStaticText(_:))) }()
extension UILabel { open override class func initialize() { _ = swizzleTextValue } @objc fileprivate func setStaticText(_ text: String?) { setStaticText(text) // You actions } }
Плохо!
extension UILabel { static func swizzleText() { _ = swizzleTextValue } @objc fileprivate func setStaticText(_ text: String?) { setStaticText(text) // You actions } }
extension UILabel { static func swizzleText() { _ = swizzleTextValue } // ... }
• Вызывать swizzleText(): • Где нибудь в AppDelegate или его проксировании
• Вызывать в load() у UILabel в Obj-c
let value = clock() for i in 0..<1000000 { cell.textLabel?.text = "\(i)" } let result = Double(clock() - value)
print(result)
До свизлинга Плосле свизлинга
2463609.0 2665523.0
2238332.0 2565639.0
2240086.0 2560924.0
2278225.0 2579298.0
2247269.0 2561646.0
2246613.0 2563499.0
2228041.0 2571111.0
15%
private var swizzleTextValue: Void = { swizzleMethods(objectClass: UILabel.self, originalSelector: #selector(setter: UILabel.text), swizzledSelector: #selector(UILabel.setLocalizedText(_:))) }()
extension UILabel { static func swizzleText() { _ = swizzleTextValue } @objc fileprivate func setLocalizedText(_ text: String?) { if let text = text, !isInsideButton { setLocalizedText(text.tripleLengthPseudolanguage) } else { setLocalizedText(text) } }
private var isInsideButton: Bool { let superview = self.superview return superview is UIButton } }
@implementation UINavigationItem (AZTitleConfiguration)
+ (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ SwizzleInstanceMethod(self, @selector(setTitle:), @selector(az_setTitleWithConfiguration:)); }); }
@end
// We setup view with our own label, because we want to use kern spacing and other appearance staf - (void)az_setTitleWithConfiguration:(NSString *)title { if (title == nil) { title = @""; } [self az_setTitleWithConfiguration:[title uppercaseString]]; NSDictionary *attributes = [[UINavigationBar appearance] titleTextAttributes]; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:[title uppercaseString] attributes:attributes];
// … fill self.titleView if already UILabel UILabel *titleLabel = [UILabel new]; titleLabel.attributedText = attributedString; [titleLabel sizeToFit]; self.titleView = titleLabel; }
// We setup view with our own label, because we want to use kern spacing and other appearance staf - (void)az_setTitleWithConfiguration:(NSString *)title { if (title == nil) { title = @""; } [self az_setTitleWithConfiguration:[title uppercaseString]]; NSDictionary *attributes = [[UINavigationBar appearance] titleTextAttributes]; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:[title uppercaseString] attributes:attributes]; // … fill self.titleView if already UILabel
UILabel *titleLabel = [UILabel new]; titleLabel.attributedText = attributedString; [titleLabel sizeToFit]; self.titleView = titleLabel; }
// We setup view with our own label, because we want to use kern spacing and other appearance staf - (void)az_setTitleWithConfiguration:(NSString *)title { if (title == nil) { title = @""; } [self az_setTitleWithConfiguration:[title uppercaseString]]; NSDictionary *attributes = [[UINavigationBar appearance] titleTextAttributes]; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:[title uppercaseString] attributes:attributes];
// … fill self.titleView if already UILabel UILabel *titleLabel = [UILabel new]; titleLabel.attributedText = attributedString; [titleLabel sizeToFit]; self.titleView = titleLabel; }
// We setup view with our own label, because we want to use kern spacing and other appearance staf - (void)az_setTitleWithConfiguration:(NSString *)title { if (title == nil) { title = @""; } [self az_setTitleWithConfiguration:[title uppercaseString]]; NSDictionary *attributes = [[UINavigationBar appearance] titleTextAttributes]; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:[title uppercaseString] attributes:attributes];
// … fill self.titleView if already UILabel UILabel *titleLabel = [UILabel new]; titleLabel.attributedText = attributedString; [titleLabel sizeToFit]; self.titleView = titleLabel; }
if ([self.titleView isKindOfClass:[UILabel class]]) { UILabel *label = (UILabel*)self.titleView; label.attributedText = attributedString; return; }
@interface NSLayoutConstraint (UCConstraintBuild)
@property (nonatomic, assign) IBInspectable CGFloat screenWidthPercent; @property (nonatomic, assign) IBInspectable CGFloat screenHeightPercent;
@end
@implementation NSLayoutConstraint (UCConstraintBuild)
- (void)setScreenWidthPercent:(CGFloat)screenWidthPercent { self.constant = round([self screenBounds].size.width * screenWidthPercent); }
- (CGFloat)screenWidthPercent { return (self.constant / [self screenBounds].size.width); }
@end
{ "colors": [ { "name": "lightWhite", "color": "F5F5F5" } ], "fonts": [ { "name": "bold", "fontName": "ProximaNova-Extrabld" } ] }
"code_templates": { "font": "UIFont(.$name, size: $size)", "textColor": "UIColor(.$)", "backgroundColor": "UIColor(.$)" }
"styles": { "text.default": { "font.size": 20, "font.name": "SFUIText-Light", "textColor": "red" }, "text.title": { "parents": ["text.default"], "font.name": "bold", "textColor": "$themeColor" } }
extension UILabel: Stylable { func apply(style: Style) { // ... } }
label.apply(style: Styles.Text.Title)
@objc protocol Foo { init() }
final class Bar: Foo { init() {} deinit { print("destroying") } }
let x: Foo.Type = Bar.self _ = x.init()
@objc protocol Foo { init() }
final class Bar: Foo { init() {} deinit { print("destroying") } }
let x: Foo.Type = Bar.self _ = x.init()
protocol Foo { init() }
final class Bar: Foo { init() {} deinit { print("destroying") } }
let x: Foo.Type = Bar.self _ = x.init()