Skip to content

Commit

Permalink
Merge pull request #41 from surfstudio/CommonButton
Browse files Browse the repository at this point in the history
Common button и UIImageExtensions
  • Loading branch information
LastSprint authored Nov 4, 2019
2 parents ba6dcdd + 10db031 commit 067ea72
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 0 deletions.
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pod 'SurfUtils/$UTIL_NAME$', :git => "https://github.com/surfstudio/iOS-Utils.gi
- [SkeletonView](#skeletonview) - cпециальная кастомная View для создания skeleton loader'ов
- [OTPField](#otpfield) - кастомный филд для работы с One Time Password
- [XibView](#xibview) - для работы UIView + xib
- [UIImageExtensions](#uiimageextensions) - набор часто используемых extensions для UIImage
- [CommonButton](#commonbutton) - Базовый класс для кнопки

## Утилиты

Expand Down Expand Up @@ -311,6 +313,37 @@ required init?(coder aDecoder: NSCoder) {
}
```

### UIImageExtensions

Набор часто используемых extensions для работы с UIImage

* Инициализатор позволяющий создать картинку с заданным цветом и размером

```swift
convenience init?(color: UIColor?, size: CGSize = CGSize(width: 1, height: 1))
```

* Метод **mask** – позволяет сделать картинку с заданным цветом или изменить параметры альфы у цвета картинки

```swift
func mask(with color: UIColor) -> UIImage
func mask(with alpha: CGFloat) -> UIImage
```

### CommonButton

Базовый класс для UIButton. Упрощает работу с доступными у класса UIButton параметрами.

Базовые возможности:

* Устанавливать бекграунд у кнопки для массива состояний
* Устанавливать цвет тайтла кнопки для массива состояний
* Устанавливать значения для border у кнопки
* Изменять cornerRadius
* Увеличивать область нажатия у кнопки
* Устанавливать значение тайтла для всех состояний сразу
* Устанавливать значение картинки кнопки для всех состояний сразу

## Версионирование

В качестве принципа версионирования используется [Семантическое версионирования (Semantic Versioning)](https://semver.org/).
Expand Down
10 changes: 10 additions & 0 deletions SurfUtils.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,14 @@ Pod::Spec.new do |s|
sp.framework = 'UIKit'
end

s.subspec 'UIImageExtensions' do |sp|
sp.source_files = 'Utils/Utils/UIImage/UIImageExtensions.swift'
sp.framework = 'UIKit'
end

s.subspec 'CommonButton' do |sp|
sp.source_files = 'Utils/Utils/CommonButton/CommonButton.swift', 'Utils/Utils/UIImage/UIImageExtensions.swift'
sp.framework = 'UIKit'
end

end
24 changes: 24 additions & 0 deletions Utils/Utils.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
4F3ED9E9211C27CF0030DD45 /* Utils.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F3ED9DF211C27CF0030DD45 /* Utils.framework */; };
4F3ED9F0211C27CF0030DD45 /* Utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F3ED9E2211C27CF0030DD45 /* Utils.h */; settings = {ATTRIBUTES = (Public, ); }; };
4F3ED9FC211C27FD0030DD45 /* String+Attributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F3ED9FB211C27FD0030DD45 /* String+Attributes.swift */; };
5709EC5D236F4C6500EEBD93 /* CommonButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5709EC5C236F4C6500EEBD93 /* CommonButton.swift */; };
5709EC6A236F562400EEBD93 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5709EC69236F562400EEBD93 /* UIImageExtensions.swift */; };
80437D26214045EF0095A8D0 /* BrightSide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80437D25214045EF0095A8D0 /* BrightSide.swift */; };
8953A46D23560A2F007AD110 /* OTPField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8953A46C23560A2F007AD110 /* OTPField.swift */; };
8953A46F23560A4C007AD110 /* OTPField.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8953A46E23560A4C007AD110 /* OTPField.xib */; };
Expand Down Expand Up @@ -59,6 +61,8 @@
4F3ED9E8211C27CF0030DD45 /* UtilsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UtilsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
4F3ED9EF211C27CF0030DD45 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4F3ED9FB211C27FD0030DD45 /* String+Attributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Attributes.swift"; sourceTree = "<group>"; };
5709EC5C236F4C6500EEBD93 /* CommonButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonButton.swift; sourceTree = "<group>"; };
5709EC69236F562400EEBD93 /* UIImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageExtensions.swift; sourceTree = "<group>"; };
80437D25214045EF0095A8D0 /* BrightSide.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrightSide.swift; sourceTree = "<group>"; };
8953A46C23560A2F007AD110 /* OTPField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OTPField.swift; sourceTree = "<group>"; };
8953A46E23560A4C007AD110 /* OTPField.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OTPField.xib; sourceTree = "<group>"; };
Expand Down Expand Up @@ -137,6 +141,7 @@
4F3ED9E1211C27CF0030DD45 /* Utils */ = {
isa = PBXGroup;
children = (
5709EC5B236F4C2200EEBD93 /* CommonButton */,
18F2361221D214CC00169AC9 /* Dictionary */,
902C67EA21E4D1EF007B13CC /* ItemsScrollManager */,
80437D24214045B30095A8D0 /* BrightSide */,
Expand All @@ -145,6 +150,7 @@
907F0FE421DCD375001CCB07 /* SettingsRouter */,
A439074C21F5C5510034C455 /* SkeletonView */,
4F3ED9FA211C27E80030DD45 /* String */,
5709EC68236F55AA00EEBD93 /* UIImage */,
907F0FE121DCD1DB001CCB07 /* UINavigationController */,
902CA33F21E732F700396923 /* UIView */,
E9B06306214691F30080C391 /* VibrationFeedbackManager */,
Expand Down Expand Up @@ -175,6 +181,22 @@
path = String;
sourceTree = "<group>";
};
5709EC5B236F4C2200EEBD93 /* CommonButton */ = {
isa = PBXGroup;
children = (
5709EC5C236F4C6500EEBD93 /* CommonButton.swift */,
);
path = CommonButton;
sourceTree = "<group>";
};
5709EC68236F55AA00EEBD93 /* UIImage */ = {
isa = PBXGroup;
children = (
5709EC69236F562400EEBD93 /* UIImageExtensions.swift */,
);
path = UIImage;
sourceTree = "<group>";
};
80437D24214045B30095A8D0 /* BrightSide */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -424,10 +446,12 @@
A439074E21F5C5880034C455 /* SkeletonView.swift in Sources */,
80437D26214045EF0095A8D0 /* BrightSide.swift in Sources */,
898845202360482D004940DC /* UIView+XibSetup.swift in Sources */,
5709EC5D236F4C6500EEBD93 /* CommonButton.swift in Sources */,
9087BC5221EF3BE700FCE1E1 /* CommonKeyboardPresentable.swift in Sources */,
9087BC5021EF3BD400FCE1E1 /* KeyboardObservable.swift in Sources */,
E9B0630E214693160080C391 /* UIDevice+hasHapticFeedback.swift in Sources */,
90718AF121EA370000C81002 /* KeyboardNotificationsObserver.swift in Sources */,
5709EC6A236F562400EEBD93 /* UIImageExtensions.swift in Sources */,
8953A46D23560A2F007AD110 /* OTPField.swift in Sources */,
4F3ED9FC211C27FD0030DD45 /* String+Attributes.swift in Sources */,
902CA34121E7331E00396923 /* UIView+BlurBuilder.swift in Sources */,
Expand Down
106 changes: 106 additions & 0 deletions Utils/Utils/CommonButton/CommonButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//
// CommonButton.swift
// Utils
//
// Created by Александр Чаусов on 28/01/2019.
// Copyright © 2019 Surf. All rights reserved.
//

import UIKit

open class CommonButton: UIButton {

// MARK: - Public Properties

public var borderColor: UIColor? {
didSet {
layer.borderColor = borderColor?.cgColor
}
}

public var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}

public var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}

/// Increase touch area
public var addedTouchArea: CGFloat = 0.0

// MARK: - Initialization

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

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

override open func awakeFromNib() {
super.awakeFromNib()
}

// MARK: - UIButton

override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let newBound = CGRect(
x: bounds.origin.x - addedTouchArea,
y: bounds.origin.y - addedTouchArea,
width: bounds.width + 2 * addedTouchArea,
height: bounds.height + 2 * addedTouchArea
)
return newBound.contains(point)
}

// MARK: - Public Methods

/// Method set title for all states
public func setTitleForAllState(_ title: String?) {
setTitle(title, for: .normal)
setTitle(title, for: .disabled)
setTitle(title, for: .highlighted)
setTitle(title, for: .selected)
}

/// Method set image for all states
/// If use alpha image with alpha mask will set for disabled, highlighted, selected states
/// - Parameters:
/// - image: Optional value for set button image
/// - alpha: Optional value for disabled, highlighted, selected states
public func setImageForAllState(_ image: UIImage?, alpha: CGFloat? = nil) {
let highlightedImage = alpha != nil
? image?.mask(with: alpha ?? 0)
: image
setImage(image, for: .normal)
setImage(highlightedImage, for: .disabled)
setImage(highlightedImage, for: .highlighted)
setImage(highlightedImage, for: .selected)
}

/// Method will set background color for control state
public func set(backgroundColor: UIColor, for state: UIControl.State) {
setBackgroundImage(UIImage(color: backgroundColor), for: state)
}

/// Method will set background color for all choosed control states
public func set(backgroundColor: UIColor, for states: [UIControl.State]) {
states.forEach { setBackgroundImage(UIImage(color: backgroundColor), for:$0) }
}

/// Method will set title color for all choosed control states
public func set(titleColor: UIColor, for states: [UIControl.State]) {
states.forEach { setTitleColor(titleColor, for: $0) }
}

}
68 changes: 68 additions & 0 deletions Utils/Utils/UIImage/UIImageExtensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//
// UIImageExtensions.swift
// Utils
//
// Created by Vladislav Krupenko on 03/11/2019.
// Copyright © 2019 Surf. All rights reserved.
//

import UIKit

public extension UIImage {

/// Init method for creating UIImage of a given color
/// - Parameters:
/// - color: Optional value, by default clear color
/// - size: Optional value, by default size 1*1
convenience init?(color: UIColor?, size: CGSize = CGSize(width: 1, height: 1)) {
let color = color ?? UIColor.clear
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

guard let cgImage = image?.cgImage else {
return nil
}
self.init(cgImage: cgImage)
}

/// Method returns UIImage with given tint color
func mask(with color: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
defer { UIGraphicsEndImageContext() }

guard let context = UIGraphicsGetCurrentContext() else {
return self
}
context.translateBy(x: 0, y: self.size.height)
context.scaleBy(x: 1.0, y: -1.0)
context.setBlendMode(.normal)

let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
guard let mask = self.cgImage else {
return self
}
context.clip(to: rect, mask: mask)

color.setFill()
context.fill(rect)

guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else {
return self
}
return newImage
}

/// Method return UIImage with given alpha
func mask(with alpha: CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(at: .zero, blendMode: .normal, alpha: alpha)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage ?? self
}

}

0 comments on commit 067ea72

Please sign in to comment.