- 개인 프로젝트에서 공통으로 사용되는 Colorset 을 포함, UI Component를 프레임워크화 합니다
- Colorset에는 다크모드, 라이트 모드를 대응하는 Asset을 포함합니다
example_video.mov
Platform | Minimum Swift Version | Installation | Status |
---|---|---|---|
iOS 13.0+ / macOS 11.0+ | 5.0 | Swift Package Manager, Manual | Fully Tested |
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift
compiler.
Once you have your Swift package set up, adding MKFoundation as a dependency is as easy as adding it to the dependencies
value of your Package.swift
.
dependencies: [
.package(url: "https://github.com/vincent-k-sm/MKFoundation", .upToNextMajor(from: "1.0.3"))
]
If you prefer not to use any of the aforementioned dependency managers, you can integrate MKFoundation into your project manually.
-
Open up Terminal,
cd
into your top-level project directory, and run the following command "if" your project is not initialized as a git repository:$ git init
-
Add MKFoundation as a git submodule by running the following command:
$ git submodule add https://github.com/vincent-k-sm/MKFoundation
After download We Suggest Remove
Example
Folder When Embed -
Click on the
+
button under th Frameworks, Libraries, and Embedded Content -
Click on the
Add Other
and Select inMKFoundation
folder -
Drag the
MKFoundation
folder into the Project Navigator of your application's Xcode project.It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter.
-
And that's it!
public enum ButtonTypes: CaseIterable {
case red
case orange
case yellow
case green
case blue
case pink
case purple
case dark
case primary
case white
case grey
}
public enum ButtonSize: CaseIterable {
case medium
case small
var style: ButtonSizeModel {
switch self {
case .medium:
let model = ButtonSizeModel(height: 48.0)
return model
case .small:
let model = ButtonSizeModel(height: 44.0)
return model
}
}
}
- setBackgroundColor
- 버튼 배경색을 지정합니다
func setBackgroundColor(
_ color: UIColor,
for state: UIControl.State
) {
- alignTextBelow
- 버튼 내 이미지와 타이틀 간의 간격을 조정합니다
- (iOS 15에서 추가된
UIButton.Configuration
은 향 후 대응 예정입니다)
- (iOS 15에서 추가된
- 버튼 내 이미지와 타이틀 간의 간격을 조정합니다
func alignTextBelow(
spacing: CGFloat = 2.0
) {
- updateTitleText
- Foundation으로 Title 없이 설정한 버튼의 Title만 Update하고자 하는 경우 사용할 수 있습니다
- 내부에서 SetTitle에 자동으로 처리하도록 개선이 필요합니다
- Foundation으로 Title 없이 설정한 버튼의 Title만 Update하고자 하는 경우 사용할 수 있습니다
func updateTitleText(
text: String,
status: [UIControl.State] = [.normal, .selected, .disabled, .highlighted]
) {
func setButtonLayout(
title: String = "",
size: ButtonSize,
primaryType: ButtonTypes,
outline: Bool = false
) {
ButtonListViewController
lazy var mkButton: UIButton = {
let v = UIButton()
v.setTitle("Button", for: .normal)
return v
}()
-----------------------------------------
self.mkButton
.setButtonLayout(
title: "지정할 Title을 입력하세요",
size: .medium,
primaryType: buttonType,
outline: self.isOutLine
)
- Colors 는 Autogen Code 입니다
- Source/ 내
Assets.xcassets
파일의Colors 폴더
을 참조하여 자동으로 enum이 생성됩니다
run
- cd Scripts
- sh gen_colorset.sh
- setColorSet
- 생성된 Colorset 을 기준으로 UIColor를 반환합니다
static func setColorSet(_ colorRawValue: Colors) -> UIColor {
var color: UIColor = .black
color = UIColor(named: colorRawValue.rawValue, in: Bundle.module, compatibleWith: nil)!
return color
}
- 상기 Autogen을 통해 생성되는 코드는 아래와 같습니다
public enum Colors: String {
case background
case background_elevated
...
}
self.view.backgroundColor = UIColor.setColorSet(.background)
- Text View 의 타입을 지정합니다
- outline 과 fill 로 설정할 수 있으며 fill 은 배경색과 함께 옅은 outline으로 설정됩니다
public enum TextViewTypes: CaseIterable {
case outLine
case fill
}
@objc public enum TextViewStatus: Int, CaseIterable {
case normal // 기본 상태
case activate // Focused 상태
case error // 에러
case disabled // 비 활성화
}
/// 텍스트 뷰를 구성하는 값을 적용합니다
/// - Parameters:
/// - textViewHeight: Textview 높이를 고정하는 경우 사용됩니다
/// - placeHolder: placeholer text
/// - limitCount: 최대 글자 수
/// - autoLimitCountErrorMessage: 최대 글자수 도달 시 해당 메시지로 에러가 설정됩니다
/// - title: 텍스트 필드 제목 영역 입니다 적용 시 최대 높이가 변경됩니다
/// - helperText: 하단 설명 영역입니다 적용 시 최대 높이가 변경됩니다
/// - counter: 상단 카운트 설정 여부입니다 적용 시 최대 높이가 변경됩니다
/// - doneAccessory : 키보드의 닫기 버튼을 추가합니다
/// - clearAccessory : 텍스트 뷰를 클리어하는 버튼이 사용됩니다
public struct MKTextViewOptions {
public var textViewHeight: CGFloat = 0.0
public var inputType: TextViewTypes = .outLine
public var placeHolder: String = ""
public var limitCount: Int = 0
public var autoLimitCountErrorMessage: String? = nil
public var title: String? = nil
public var helperText: String? = nil
public var counter: Bool = false
public var doneAccessory: Bool = false
public var clearAccessory: Bool = false
}
@objc public protocol MKTextViewDelegate: AnyObject {
/// An textView did count limitted
/// - Parameter textView: The MKTextView that textView was called in
/// - Parameter status: textView status - textViewStatus
/// - important : Trigger Only Limit Count is Not 0
@objc optional func textViewLimitted(_ textView: MKTextView, limitted: Bool)
/// An textView did change Status
/// - Parameter textView: The MKTextView that textView was called in
/// - Parameter status: textView status - textViewStatus
@objc optional func textViewStatusDidChange(_ textView: MKTextView, status: TextViewStatus)
/// An textView did change Text
/// - Parameter textView: The MKTextView that textView was called in
/// - Parameter text: textView text
@objc optional func textViewTextDidChange(_ textView: MKTextView, text: String)
/// An textView DidBeginEditing
/// - Parameter textView: The MKTextView that textView was called in
@objc optional func textViewTextDidBeginEditing(_ textView: MKTextView)
/// An textView textViewTextDidEndEditing
/// - Parameter textView: The MKTextView that textView was called in
@objc optional func textViewTextDidEndEditing(_ textView: MKTextView)
}
-
TextView를 Tableview에서 활용하는 경우 높이값에 따라
UITableView.automaticDimension
이 필요한 경우를 위해 Configure 시tableview
를 추가할 수 있습니다 -
Configure TextView
/* class MKTextView */
func configure(
option: MKTextViewOptions,
tableView: UITableView? = nil,
customToolbar: Bool = false
) {
/* initialize TextView*/
lazy var mkTextView: MKTextView = {
let v = MKTextView()
return v
}()
....
/* Set TextView Options */
let option = MKTextViewOptions(
inputType: .outLine,
placeHolder: "TextView PlaceHolder",
limitCount: 10,
autoLimitCountErrorMessage: "Text is Limitted",
title: "Title + Counter + Limit Description",
helperText: "description for TextView",
counter: true
)
....
/* Configure to TextView*/
mkTextView.configure(option: op, tableView: tableView)
- Text Field 의 타입을 지정합니다
- outline 과 fill 로 설정할 수 있으며 fill 은 배경색과 함께 옅은 outline으로 설정됩니다
public enum TextFieldTypes: CaseIterable {
case outLine
case fill
}
@objc public enum TextFieldStatus: Int, CaseIterable {
case normal // 기본 상태
case activate // Focused 상태
case error // 에러
case disabled // 비 활성화
}
/// 텍스트 필드를 구성하는 값을 적용합니다
/// - Parameters:
/// - placeHolder: placeholer text
/// - limitCount: 최대 글자 수
/// - autoLimitCountErrorMessage: 최대 글자수 도달 시 해당 메시지로 에러가 설정됩니다
/// - title: 텍스트 필드 제목 영역 입니다 적용 시 최대 높이가 변경됩니다
/// - helperText: 하단 설명 영역입니다 적용 시 최대 높이가 변경됩니다
/// - counter: 상단 카운트 설정 여부입니다 적용 시 최대 높이가 변경됩니다
/// - leadingIcon : 좌측 이미지 심볼을 적용합니다 이미지가 있는 경우 레이아웃이 변경됩니다
public struct MKTextFieldOptions {
public var inputType: TextFieldTypes = .outLine
public var placeHolder: String = ""
public var limitCount: Int = 0
public var autoLimitCountErrorMessage: String? = nil
public var title: String? = nil
public var helperText: String? = nil
public var counter: Bool = false
public var leadingIcon: UIImage? = nil
}
@objc public protocol MKTextViewDelegate: AnyObject {
/// override Textfield
@objc optional func textFieldShouldReturn(_ textField: MKTextField) -> Bool
@objc optional func textFieldShouldClear(_ textField: MKTextField) -> Bool
/// An textfield did count limitted
/// - Parameter textField: The MKTextField that textfield was called in
/// - Parameter status: textfield status - TextfieldStatus
/// - important : Trigger Only Limit Count is Not 0
@objc optional func textFieldLimitted(_ textField: MKTextField, limitted: Bool)
// An textfield did change Status
/// - Parameter textField: The MKTextField that textfield was called in
/// - Parameter status: textfield status - TextfieldStatus
@objc optional func textFieldStatusDidChange(_ textField: MKTextField, status: TextFieldStatus)
/// An textfield did change Text
/// - Parameter textField: The MKTextField that textfield was called in
/// - Parameter text: textfield text
@objc optional func textFieldTextDidChange(_ textField: MKTextField, text: String)
/// An textfield DidBeginEditing
/// - Parameter textField: The MKTextField that textfield was called in
@objc optional func textFieldTextDidBeginEditing(_ textField: MKTextField)
/// An textfield textFieldTextDidEndEditing
/// - Parameter textField: The MKTextField that textfield was called in
@objc optional func textFieldTextDidEndEditing(_ textField: MKTextField
}
-
TextView를 Tableview에서 활용하는 경우 높이값에 따라
UITableView.automaticDimension
이 필요한 경우를 위해 Configure 시tableview
를 추가할 수 있습니다 -
Configure TextField
/* class MKTextField */
func configure(
option: MKTextFieldOptions,
tableView: UITableView? = nil
) {
/* initialize TextField*/
lazy var mkTextField: MKTextField = {
let v = MKTextField()
return v
}()
....
/* Set MKTextField Options */
let option = MKTextFieldOptions(
inputType: .outLine,
placeHolder: "TextField PlaceHolder",
limitCount: 100,
autoLimitCountErrorMessage: nil,
title: "Title With Description + Counter",
helperText: "description for TextField",
leadingIcon: UIImage(named: "ic_search") ?? nil,
counter: true
)
....
/* Configure to TextField*/
mkTextField.configure(option: option, tableView: tableView)
- SelectBox 의 타입을 지정합니다
- outline 과 fill 로 설정할 수 있으며 fill 은 배경색과 함께 옅은 outline으로 설정됩니다
public enum SelectBoxTypes: CaseIterable {
case outLine
case fill
}
@objc public enum SelectBoxStatus: Int, CaseIterable {
case normal // 기본 상태
case activate // Focused 상태
case error // 에러
case disabled // 비 활성화
}
/// 셀렉트 박스 를 구성하는 값을 적용합니다
/// - Parameters:
/// - placeHolder: placeholer text
/// - title: 필드 제목 영역 입니다 적용 시 최대 높이가 변경됩니다
/// - helperText: 하단 설명 영역입니다 적용 시 최대 높이가 변경됩니다
public struct MKSelectBoxOptions {
public var inputType: SelectBoxTypes = .outLine
public var placeHolder: String = ""
public var title: String? = nil
public var helperText: String? = nil
}
public protocol MKSelectBoxDelegate: AnyObject {
// Select box Selected
/// - Parameter selectBox: The MKSelectBox that selectBox was called in
func didSelected(_ selectBox: MKSelectBox)
// Select box didChangeStatus
/// - Parameter selectBox: The MKSelectBox that selectBox was called in
/// - Parameter status: selectBox status - SelectBoxStatus
func didChangeStatus(_ selectBox: MKSelectBox, status: SelectBoxStatus)
}
-
TextView를 Tableview에서 활용하는 경우 높이값에 따라
UITableView.automaticDimension
이 필요한 경우를 위해 Configure 시tableview
를 추가할 수 있습니다 -
Configure SelectBox
/* class MKSelectBox */
func configure(
option: MKSelectBoxOptions,
tableView: UITableView? = nil
) {
/* initialize SelectBox*/
lazy var mkSelectBox: MKSelectBox = {
let v = MKSelectBox()
return v
}()
....
/* Set MKSelectBox Options */
let option = MKSelectBoxOptions(
inputType: .outLine,
placeHolder: "Select box PlaceHolder",
title: "Title With Description",
helperText: "description for select box"
)
....
/* Configure to TextField*/
mkSelectBox.configure(option: option, tableView: tableView)
public struct SwitchConstants {
/// 길이
static var viewWidth: CGFloat = 48
/// 높이
static var viewHeight: CGFloat = 28
/// 애니메이션 시간
static var animateDuration: CGFloat = 0.25
/// 버튼 높이
static var circleHeight: CGFloat = 24
/// 버튼 길이
static var circleWidth: CGFloat = 24
/// 활성화 + 켜졌을 경우 배경 색
static var enableOnBackgroundColor: UIColor = UIColor.setColorSet(.purple500)
/// 활성화 + 꺼졌을 경우 배경 색
static var enableOffBackgroundColor: UIColor = UIColor.setColorSet(.grey100)
/// 비 활성화 + 켜졌을 경우 배경 색
static var disableOnBackgroundColor: UIColor = UIColor.setColorSet(.grey300)
/// 비 활성화 + 꺼졌을 경우 배경 색
static var disableOffBackgroundColor: UIColor = UIColor.setColorSet(.grey300)
}
public protocol SwitchDelegate: AnyObject {
func isOnValueChange(switch: MKSwitch, isOn: Bool)
}
- Disabled 상태에서는
isOn
status
가return
됩니다
/* class MKSwitch: UIView */
---
/// set switch status
public func setSwitch(isOn: Bool)
/// set isEnabled
public var isEnabled: Bool = true
/// initialize switch
lazy var mkSwitch: MKSwitch = {
let v = MKSwitch()
return v
}()
/// 체크박스를 구성하는 값을 적용합니다
/// - Parameters:
/// - text : 컨텐츠 내용
/// - isEnabled : enable 여부를 설정합니다
/// - textColor : 제목 색상 (title Label에 직접 접근하여 변경할 수 있습니다)
/// - isOn: On/Off Status
public struct MKCheckBoxOptions {
public var text: String? = nil
public var isEnabled: Bool = true
public var textColor: Colors = .text_primary
public var isOn: Bool = false
}
public protocol MKCheckBoxDelegate: AnyObject {
func didSelected(_ selectBox: MKCheckBox)
func didChangeStatus(_ selectBox: MKCheckBox, status: Bool)
}
/// initialize Checkbox
lazy var mkCheckBox: MKCheckBox = {
let v = MKCheckBox()
return v
}()
/// set checkbox options
let option = MKCheckBoxOptions(
text: "enabled + isOn",
isEnabled: true,
textColor: .text_primary,
isOn: true
)
/// configure
mkCheckBox.configure(option: option)
- alignTextBelow
- iOS 15에서 추가된
UIButton.Configuration
대응
- iOS 15에서 추가된
- updateTitleText
- 내부에서 SetTitle에 자동으로 처리하도록 개선 필요
- 각 Foundation 의 속성값을 유동적으로 조정할 수 있도록 enum 에서 struct 로 변경