├── .gitignore ├── .swift-version ├── Example ├── Source │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── LaunchImage.launchimage │ │ │ └── Contents.json │ │ ├── add.imageset │ │ │ ├── Contents.json │ │ │ └── add.png │ │ └── view.imageset │ │ │ ├── Contents.json │ │ │ ├── view.png │ │ │ └── view@2x.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── ControlViewController.swift │ ├── Info.plist │ ├── ViewController.swift │ └── ViewViewController.swift └── ViewStyleExample.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ └── contents.xcworkspacedata ├── LICENSE ├── README.md ├── README.zh-cn.md ├── Source ├── Core │ ├── Property.swift │ └── UIViewStyle.swift ├── Extensions │ ├── UIButton+Style.swift │ ├── UIImageView+Style.swift │ ├── UILabel+Style.swift │ ├── UIScrollView+Style.swift │ ├── UISwitch+Style.swift │ ├── UITableView+Style.swift │ ├── UITextField+Style.swift │ └── UITextView+Style.swift ├── Info.plist └── ViewStyle.h ├── Tests ├── Info.plist └── Tests.swift ├── ViewStyle.podspec ├── ViewStyle.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata └── ViewStyle.xcworkspace └── contents.xcworkspacedata /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /Example/Source/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ViewStyleExample 4 | // 5 | // Created by Konka on 2017/2/1. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/Source/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /Example/Source/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Source/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "minimum-system-version" : "7.0", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "orientation" : "portrait", 11 | "idiom" : "iphone", 12 | "minimum-system-version" : "7.0", 13 | "subtype" : "retina4", 14 | "scale" : "2x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Source/Assets.xcassets/add.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "add.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Source/Assets.xcassets/add.imageset/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/southpeak/ViewStyle/06fbcc0783902d49df6bcbe47fe3a322f4dba422/Example/Source/Assets.xcassets/add.imageset/add.png -------------------------------------------------------------------------------- /Example/Source/Assets.xcassets/view.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "view.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "view@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/Source/Assets.xcassets/view.imageset/view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/southpeak/ViewStyle/06fbcc0783902d49df6bcbe47fe3a322f4dba422/Example/Source/Assets.xcassets/view.imageset/view.png -------------------------------------------------------------------------------- /Example/Source/Assets.xcassets/view.imageset/view@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/southpeak/ViewStyle/06fbcc0783902d49df6bcbe47fe3a322f4dba422/Example/Source/Assets.xcassets/view.imageset/view@2x.png -------------------------------------------------------------------------------- /Example/Source/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Example/Source/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Example/Source/ControlViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ControlViewController.swift 3 | // ViewStyleExample 4 | // 5 | // Created by Konka on 2017/2/1. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ViewStyle 11 | 12 | class ControlViewController: UIViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | // Do any additional setup after loading the view. 18 | 19 | self.view.backgroundColor = .white 20 | self.title = "Control" 21 | 22 | let label = UILabel(frame: CGRect(x: 10, y: 100, width: 200, height: 40)) 23 | label.text = "This is a label" 24 | label.mi_styles = labelStyle 25 | self.view.addSubview(label) 26 | 27 | let button = UIButton(frame: CGRect(x: 10, y: 150, width: 300, height: 40)) 28 | button.setTitle("This is a button", for: .normal) 29 | button.mi_styles = buttonStyle 30 | self.view.addSubview(button) 31 | 32 | let switchButton = UISwitch(frame: CGRect(x: 10, y: 200, width: 60, height: 40)) 33 | switchButton.mi_styles = switchStyle 34 | self.view.addSubview(switchButton) 35 | } 36 | } 37 | 38 | extension ControlViewController { 39 | var labelStyle: [MIProperty: Any] { 40 | return [ 41 | .font: UIFont(name: "Helvetica Neue", size: 30)!, 42 | .textColor: UIColor.blue, 43 | .textAlignment: NSTextAlignment.center, 44 | .shadowColor: UIColor.red, 45 | .shadowOffset: CGSize(width: 3.0, height: 3.0), 46 | .layerBorderWidth: 1.0, 47 | .layerBorderColor: UIColor.blue 48 | ] 49 | } 50 | 51 | var buttonStyle: [MIProperty: Any] { 52 | return [ 53 | .backgroundColor: UIColor.blue, 54 | .titleColorNormal: UIColor.white, 55 | .titleColorHightlighted: UIColor.gray, 56 | .titleShadowColorNormal: UIColor.yellow, 57 | .imageNormal: UIImage(named: "add")!, 58 | .titleEdgeInsets: UIEdgeInsets(top: 0.0, left: 50, bottom: 0.0, right: 5.0), 59 | .imageEdgeInsets: UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 100.0) 60 | ] 61 | } 62 | 63 | var switchStyle: [MIProperty: Any] { 64 | return [ 65 | .onTintColor: UIColor.red, 66 | .tintColor: UIColor.blue, 67 | .thumbTintColor: UIColor.yellow, 68 | .onImage: UIImage(), 69 | .offImage: UIImage() 70 | ] 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Example/Source/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Example/Source/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // ViewStyleExample 4 | // 5 | // Created by Konka on 2017/2/1. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ViewStyle 11 | 12 | class ViewController: UIViewController { 13 | 14 | var tableView: UITableView? 15 | 16 | struct DataStruct { 17 | let title: String 18 | let controller: AnyClass 19 | } 20 | 21 | var data: [DataStruct] = [] 22 | 23 | override func viewDidLoad() { 24 | super.viewDidLoad() 25 | // Do any additional setup after loading the view, typically from a nib. 26 | 27 | self.title = "View Style Example" 28 | 29 | data = [ 30 | DataStruct(title: "UIView", controller: ViewViewController.self), 31 | DataStruct(title: "UIControl", controller: ControlViewController.self) 32 | ] 33 | 34 | tableView = UITableView(frame: self.view.bounds) 35 | tableView!.dataSource = self 36 | tableView!.delegate = self 37 | tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell") 38 | 39 | tableView!.mi_styles = self.tableViewStyle 40 | 41 | self.view.addSubview(tableView!) 42 | } 43 | } 44 | 45 | // MARK: - UITableViewDelegate 46 | 47 | extension ViewController: UITableViewDelegate { 48 | 49 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 50 | 51 | let clazz = data[indexPath.row].controller as! UIViewController.Type 52 | let controller = clazz.init() 53 | self.navigationController?.pushViewController(controller, animated: true) 54 | } 55 | } 56 | 57 | // MARK: - UITableViewDataSource 58 | 59 | extension ViewController: UITableViewDataSource { 60 | 61 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 62 | return data.count 63 | } 64 | 65 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 66 | 67 | let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") 68 | cell?.textLabel?.text = data[indexPath.row].title 69 | return cell! 70 | } 71 | } 72 | 73 | // MARK: - Table View Style 74 | 75 | extension ViewController { 76 | var tableViewStyle: [MIProperty: Any] { 77 | return [ 78 | .rowHeight: 60, 79 | .separatorStyle: UITableViewCellSeparatorStyle.singleLine, 80 | .separatorColor: UIColor.lightGray, 81 | .backgroundView: UIView(), 82 | .separatorInset: UIEdgeInsets(top: 10.0, left: 5.0, bottom: 3.0, right: 10.0), 83 | .cellLayoutMarginsFollowReadableWidth: true 84 | ] 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Example/Source/ViewViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewViewController.swift 3 | // ViewStyleExample 4 | // 5 | // Created by Konka on 2017/2/1. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ViewStyle 11 | 12 | class ViewViewController: UIViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | // Do any additional setup after loading the view. 18 | 19 | self.view.backgroundColor = .white 20 | self.title = "View" 21 | 22 | let view1 = UIView(frame: CGRect(x: 10, y: 100, width: 200, height: 100)) 23 | view1.mi_styles = self.normalStyle 24 | self.view.addSubview(view1) 25 | 26 | let view2 = UIView(frame: CGRect(x: 10, y: 220, width: 200, height: 100)) 27 | view2.backgroundColor = UIColor.blue 28 | view2.mi_styles = self.normalStyle 29 | view2.mi_styles = self.layerStyle 30 | self.view.addSubview(view2) 31 | 32 | let imageView = UIImageView(frame: CGRect(x: 10, y: 340, width: 200, height: 100)) 33 | imageView.mi_styles = self.imageStyle 34 | self.view.addSubview(imageView) 35 | } 36 | 37 | } 38 | 39 | extension ViewViewController { 40 | 41 | var normalStyle: [MIProperty: Any] { 42 | return [ 43 | .backgroundColor: UIColor.blue, 44 | .alpha: 0.5, 45 | .isOpaque: true, 46 | .tintColor: UIColor.red, 47 | .tintAdjustmentMode: UIViewTintAdjustmentMode.automatic, 48 | .clipsToBounds: true, 49 | .clearsContextBeforeDrawing: true, 50 | ] 51 | } 52 | 53 | var layerStyle: [MIProperty: Any] { 54 | return [ 55 | .clipsToBounds: false, 56 | .layerBorderWidth: 1.0, 57 | .layerBorderColor: UIColor.red.cgColor, 58 | .layerShadowRadius: 4.0, 59 | .layerShadowColor: UIColor.green.cgColor, 60 | .layerShadowOffset: CGSize(width: 10, height: 10), 61 | .layerShadowOpacity: 0.8 62 | ] 63 | } 64 | 65 | var imageStyle: [MIProperty: Any] { 66 | return [ 67 | .layerMasksToBounds: true, 68 | .layerCornerRadius: 8.0, 69 | .image: UIImage(named: "view")! 70 | ] 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Example/ViewStyleExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E15AF0FF1E41B6C20082C755 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF0F71E41B6C20082C755 /* AppDelegate.swift */; }; 11 | E15AF1001E41B6C20082C755 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E15AF0F81E41B6C20082C755 /* Assets.xcassets */; }; 12 | E15AF1011E41B6C20082C755 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E15AF0F91E41B6C20082C755 /* LaunchScreen.storyboard */; }; 13 | E15AF1021E41B6C20082C755 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E15AF0FB1E41B6C20082C755 /* Main.storyboard */; }; 14 | E15AF1041E41B6C20082C755 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF0FE1E41B6C20082C755 /* ViewController.swift */; }; 15 | E15AF1281E42271B0082C755 /* ViewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF1271E42271B0082C755 /* ViewViewController.swift */; }; 16 | E15AF12A1E42272D0082C755 /* ControlViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF1291E42272D0082C755 /* ControlViewController.swift */; }; 17 | E15AF12D1E42281B0082C755 /* ViewStyle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E15AF12C1E42281B0082C755 /* ViewStyle.framework */; }; 18 | E15AF13B1E42291F0082C755 /* ViewStyle.framework in Copy Framework */ = {isa = PBXBuildFile; fileRef = E15AF1351E4228D90082C755 /* ViewStyle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | E15AF1341E4228D90082C755 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = E15AF12F1E4228D90082C755 /* ViewStyle.xcodeproj */; 25 | proxyType = 2; 26 | remoteGlobalIDString = E15AF0AA1E41B4A80082C755; 27 | remoteInfo = ViewStyle; 28 | }; 29 | E15AF1361E4228D90082C755 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = E15AF12F1E4228D90082C755 /* ViewStyle.xcodeproj */; 32 | proxyType = 2; 33 | remoteGlobalIDString = E15AF0C81E41B5480082C755; 34 | remoteInfo = Tests; 35 | }; 36 | E15AF1381E4228F40082C755 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = E15AF12F1E4228D90082C755 /* ViewStyle.xcodeproj */; 39 | proxyType = 1; 40 | remoteGlobalIDString = E15AF0A91E41B4A80082C755; 41 | remoteInfo = ViewStyle; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXCopyFilesBuildPhase section */ 46 | E15AF13A1E4229090082C755 /* Copy Framework */ = { 47 | isa = PBXCopyFilesBuildPhase; 48 | buildActionMask = 2147483647; 49 | dstPath = ""; 50 | dstSubfolderSpec = 10; 51 | files = ( 52 | E15AF13B1E42291F0082C755 /* ViewStyle.framework in Copy Framework */, 53 | ); 54 | name = "Copy Framework"; 55 | runOnlyForDeploymentPostprocessing = 0; 56 | }; 57 | /* End PBXCopyFilesBuildPhase section */ 58 | 59 | /* Begin PBXFileReference section */ 60 | E15AF0E11E41B66E0082C755 /* ViewStyleExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ViewStyleExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | E15AF0F71E41B6C20082C755 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 62 | E15AF0F81E41B6C20082C755 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 63 | E15AF0FA1E41B6C20082C755 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 64 | E15AF0FC1E41B6C20082C755 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 65 | E15AF0FD1E41B6C20082C755 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 66 | E15AF0FE1E41B6C20082C755 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 67 | E15AF1271E42271B0082C755 /* ViewViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewViewController.swift; sourceTree = ""; }; 68 | E15AF1291E42272D0082C755 /* ControlViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlViewController.swift; sourceTree = ""; }; 69 | E15AF12C1E42281B0082C755 /* ViewStyle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ViewStyle.framework; path = "../../../Library/Developer/Xcode/DerivedData/ViewStyle-anxlnjlygbwgamasvxqsxzqmzkmc/Build/Products/Debug-iphonesimulator/ViewStyle.framework"; sourceTree = ""; }; 70 | E15AF12F1E4228D90082C755 /* ViewStyle.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ViewStyle.xcodeproj; path = ../ViewStyle.xcodeproj; sourceTree = ""; }; 71 | /* End PBXFileReference section */ 72 | 73 | /* Begin PBXFrameworksBuildPhase section */ 74 | E15AF0DE1E41B66E0082C755 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | E15AF12D1E42281B0082C755 /* ViewStyle.framework in Frameworks */, 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | /* End PBXFrameworksBuildPhase section */ 83 | 84 | /* Begin PBXGroup section */ 85 | E15AF0D81E41B66E0082C755 = { 86 | isa = PBXGroup; 87 | children = ( 88 | E15AF12F1E4228D90082C755 /* ViewStyle.xcodeproj */, 89 | E15AF0F61E41B6C20082C755 /* Source */, 90 | E15AF0E21E41B66E0082C755 /* Products */, 91 | E15AF12B1E42281B0082C755 /* Frameworks */, 92 | ); 93 | sourceTree = ""; 94 | }; 95 | E15AF0E21E41B66E0082C755 /* Products */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | E15AF0E11E41B66E0082C755 /* ViewStyleExample.app */, 99 | ); 100 | name = Products; 101 | sourceTree = ""; 102 | }; 103 | E15AF0F61E41B6C20082C755 /* Source */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | E15AF0F71E41B6C20082C755 /* AppDelegate.swift */, 107 | E15AF0F81E41B6C20082C755 /* Assets.xcassets */, 108 | E15AF0F91E41B6C20082C755 /* LaunchScreen.storyboard */, 109 | E15AF0FB1E41B6C20082C755 /* Main.storyboard */, 110 | E15AF0FD1E41B6C20082C755 /* Info.plist */, 111 | E15AF0FE1E41B6C20082C755 /* ViewController.swift */, 112 | E15AF1271E42271B0082C755 /* ViewViewController.swift */, 113 | E15AF1291E42272D0082C755 /* ControlViewController.swift */, 114 | ); 115 | path = Source; 116 | sourceTree = ""; 117 | }; 118 | E15AF12B1E42281B0082C755 /* Frameworks */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | E15AF12C1E42281B0082C755 /* ViewStyle.framework */, 122 | ); 123 | name = Frameworks; 124 | sourceTree = ""; 125 | }; 126 | E15AF1301E4228D90082C755 /* Products */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | E15AF1351E4228D90082C755 /* ViewStyle.framework */, 130 | E15AF1371E4228D90082C755 /* Tests.xctest */, 131 | ); 132 | name = Products; 133 | sourceTree = ""; 134 | }; 135 | /* End PBXGroup section */ 136 | 137 | /* Begin PBXNativeTarget section */ 138 | E15AF0E01E41B66E0082C755 /* ViewStyleExample */ = { 139 | isa = PBXNativeTarget; 140 | buildConfigurationList = E15AF0F31E41B66E0082C755 /* Build configuration list for PBXNativeTarget "ViewStyleExample" */; 141 | buildPhases = ( 142 | E15AF0DD1E41B66E0082C755 /* Sources */, 143 | E15AF0DE1E41B66E0082C755 /* Frameworks */, 144 | E15AF0DF1E41B66E0082C755 /* Resources */, 145 | E15AF13A1E4229090082C755 /* Copy Framework */, 146 | ); 147 | buildRules = ( 148 | ); 149 | dependencies = ( 150 | E15AF1391E4228F40082C755 /* PBXTargetDependency */, 151 | ); 152 | name = ViewStyleExample; 153 | productName = ViewStyleExample; 154 | productReference = E15AF0E11E41B66E0082C755 /* ViewStyleExample.app */; 155 | productType = "com.apple.product-type.application"; 156 | }; 157 | /* End PBXNativeTarget section */ 158 | 159 | /* Begin PBXProject section */ 160 | E15AF0D91E41B66E0082C755 /* Project object */ = { 161 | isa = PBXProject; 162 | attributes = { 163 | LastSwiftUpdateCheck = 0820; 164 | LastUpgradeCheck = 0820; 165 | ORGANIZATIONNAME = Minya; 166 | TargetAttributes = { 167 | E15AF0E01E41B66E0082C755 = { 168 | CreatedOnToolsVersion = 8.2.1; 169 | ProvisioningStyle = Automatic; 170 | }; 171 | }; 172 | }; 173 | buildConfigurationList = E15AF0DC1E41B66E0082C755 /* Build configuration list for PBXProject "ViewStyleExample" */; 174 | compatibilityVersion = "Xcode 3.2"; 175 | developmentRegion = English; 176 | hasScannedForEncodings = 0; 177 | knownRegions = ( 178 | en, 179 | Base, 180 | ); 181 | mainGroup = E15AF0D81E41B66E0082C755; 182 | productRefGroup = E15AF0E21E41B66E0082C755 /* Products */; 183 | projectDirPath = ""; 184 | projectReferences = ( 185 | { 186 | ProductGroup = E15AF1301E4228D90082C755 /* Products */; 187 | ProjectRef = E15AF12F1E4228D90082C755 /* ViewStyle.xcodeproj */; 188 | }, 189 | ); 190 | projectRoot = ""; 191 | targets = ( 192 | E15AF0E01E41B66E0082C755 /* ViewStyleExample */, 193 | ); 194 | }; 195 | /* End PBXProject section */ 196 | 197 | /* Begin PBXReferenceProxy section */ 198 | E15AF1351E4228D90082C755 /* ViewStyle.framework */ = { 199 | isa = PBXReferenceProxy; 200 | fileType = wrapper.framework; 201 | path = ViewStyle.framework; 202 | remoteRef = E15AF1341E4228D90082C755 /* PBXContainerItemProxy */; 203 | sourceTree = BUILT_PRODUCTS_DIR; 204 | }; 205 | E15AF1371E4228D90082C755 /* Tests.xctest */ = { 206 | isa = PBXReferenceProxy; 207 | fileType = wrapper.cfbundle; 208 | path = Tests.xctest; 209 | remoteRef = E15AF1361E4228D90082C755 /* PBXContainerItemProxy */; 210 | sourceTree = BUILT_PRODUCTS_DIR; 211 | }; 212 | /* End PBXReferenceProxy section */ 213 | 214 | /* Begin PBXResourcesBuildPhase section */ 215 | E15AF0DF1E41B66E0082C755 /* Resources */ = { 216 | isa = PBXResourcesBuildPhase; 217 | buildActionMask = 2147483647; 218 | files = ( 219 | E15AF1001E41B6C20082C755 /* Assets.xcassets in Resources */, 220 | E15AF1021E41B6C20082C755 /* Main.storyboard in Resources */, 221 | E15AF1011E41B6C20082C755 /* LaunchScreen.storyboard in Resources */, 222 | ); 223 | runOnlyForDeploymentPostprocessing = 0; 224 | }; 225 | /* End PBXResourcesBuildPhase section */ 226 | 227 | /* Begin PBXSourcesBuildPhase section */ 228 | E15AF0DD1E41B66E0082C755 /* Sources */ = { 229 | isa = PBXSourcesBuildPhase; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | E15AF1281E42271B0082C755 /* ViewViewController.swift in Sources */, 233 | E15AF0FF1E41B6C20082C755 /* AppDelegate.swift in Sources */, 234 | E15AF12A1E42272D0082C755 /* ControlViewController.swift in Sources */, 235 | E15AF1041E41B6C20082C755 /* ViewController.swift in Sources */, 236 | ); 237 | runOnlyForDeploymentPostprocessing = 0; 238 | }; 239 | /* End PBXSourcesBuildPhase section */ 240 | 241 | /* Begin PBXTargetDependency section */ 242 | E15AF1391E4228F40082C755 /* PBXTargetDependency */ = { 243 | isa = PBXTargetDependency; 244 | name = ViewStyle; 245 | targetProxy = E15AF1381E4228F40082C755 /* PBXContainerItemProxy */; 246 | }; 247 | /* End PBXTargetDependency section */ 248 | 249 | /* Begin PBXVariantGroup section */ 250 | E15AF0F91E41B6C20082C755 /* LaunchScreen.storyboard */ = { 251 | isa = PBXVariantGroup; 252 | children = ( 253 | E15AF0FA1E41B6C20082C755 /* Base */, 254 | ); 255 | name = LaunchScreen.storyboard; 256 | sourceTree = ""; 257 | }; 258 | E15AF0FB1E41B6C20082C755 /* Main.storyboard */ = { 259 | isa = PBXVariantGroup; 260 | children = ( 261 | E15AF0FC1E41B6C20082C755 /* Base */, 262 | ); 263 | name = Main.storyboard; 264 | sourceTree = ""; 265 | }; 266 | /* End PBXVariantGroup section */ 267 | 268 | /* Begin XCBuildConfiguration section */ 269 | E15AF0F11E41B66E0082C755 /* Debug */ = { 270 | isa = XCBuildConfiguration; 271 | buildSettings = { 272 | ALWAYS_SEARCH_USER_PATHS = NO; 273 | CLANG_ANALYZER_NONNULL = YES; 274 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 275 | CLANG_CXX_LIBRARY = "libc++"; 276 | CLANG_ENABLE_MODULES = YES; 277 | CLANG_ENABLE_OBJC_ARC = YES; 278 | CLANG_WARN_BOOL_CONVERSION = YES; 279 | CLANG_WARN_CONSTANT_CONVERSION = YES; 280 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 281 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 282 | CLANG_WARN_EMPTY_BODY = YES; 283 | CLANG_WARN_ENUM_CONVERSION = YES; 284 | CLANG_WARN_INFINITE_RECURSION = YES; 285 | CLANG_WARN_INT_CONVERSION = YES; 286 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 287 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 288 | CLANG_WARN_UNREACHABLE_CODE = YES; 289 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 290 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 291 | COPY_PHASE_STRIP = NO; 292 | DEBUG_INFORMATION_FORMAT = dwarf; 293 | ENABLE_STRICT_OBJC_MSGSEND = YES; 294 | ENABLE_TESTABILITY = YES; 295 | GCC_C_LANGUAGE_STANDARD = gnu99; 296 | GCC_DYNAMIC_NO_PIC = NO; 297 | GCC_NO_COMMON_BLOCKS = YES; 298 | GCC_OPTIMIZATION_LEVEL = 0; 299 | GCC_PREPROCESSOR_DEFINITIONS = ( 300 | "DEBUG=1", 301 | "$(inherited)", 302 | ); 303 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 304 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 305 | GCC_WARN_UNDECLARED_SELECTOR = YES; 306 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 307 | GCC_WARN_UNUSED_FUNCTION = YES; 308 | GCC_WARN_UNUSED_VARIABLE = YES; 309 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 310 | MTL_ENABLE_DEBUG_INFO = YES; 311 | ONLY_ACTIVE_ARCH = YES; 312 | SDKROOT = iphoneos; 313 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 314 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 315 | }; 316 | name = Debug; 317 | }; 318 | E15AF0F21E41B66E0082C755 /* Release */ = { 319 | isa = XCBuildConfiguration; 320 | buildSettings = { 321 | ALWAYS_SEARCH_USER_PATHS = NO; 322 | CLANG_ANALYZER_NONNULL = YES; 323 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 324 | CLANG_CXX_LIBRARY = "libc++"; 325 | CLANG_ENABLE_MODULES = YES; 326 | CLANG_ENABLE_OBJC_ARC = YES; 327 | CLANG_WARN_BOOL_CONVERSION = YES; 328 | CLANG_WARN_CONSTANT_CONVERSION = YES; 329 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 330 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 331 | CLANG_WARN_EMPTY_BODY = YES; 332 | CLANG_WARN_ENUM_CONVERSION = YES; 333 | CLANG_WARN_INFINITE_RECURSION = YES; 334 | CLANG_WARN_INT_CONVERSION = YES; 335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 336 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 337 | CLANG_WARN_UNREACHABLE_CODE = YES; 338 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 339 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 340 | COPY_PHASE_STRIP = NO; 341 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 342 | ENABLE_NS_ASSERTIONS = NO; 343 | ENABLE_STRICT_OBJC_MSGSEND = YES; 344 | GCC_C_LANGUAGE_STANDARD = gnu99; 345 | GCC_NO_COMMON_BLOCKS = YES; 346 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 347 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 348 | GCC_WARN_UNDECLARED_SELECTOR = YES; 349 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 350 | GCC_WARN_UNUSED_FUNCTION = YES; 351 | GCC_WARN_UNUSED_VARIABLE = YES; 352 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 353 | MTL_ENABLE_DEBUG_INFO = NO; 354 | SDKROOT = iphoneos; 355 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 356 | VALIDATE_PRODUCT = YES; 357 | }; 358 | name = Release; 359 | }; 360 | E15AF0F41E41B66E0082C755 /* Debug */ = { 361 | isa = XCBuildConfiguration; 362 | buildSettings = { 363 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 364 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 365 | DEVELOPMENT_TEAM = ""; 366 | INFOPLIST_FILE = Source/Info.plist; 367 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 368 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 369 | PRODUCT_BUNDLE_IDENTIFIER = com.example.ViewStyleExample; 370 | PRODUCT_NAME = "$(TARGET_NAME)"; 371 | SWIFT_VERSION = 3.0; 372 | }; 373 | name = Debug; 374 | }; 375 | E15AF0F51E41B66E0082C755 /* Release */ = { 376 | isa = XCBuildConfiguration; 377 | buildSettings = { 378 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 379 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 380 | DEVELOPMENT_TEAM = ""; 381 | INFOPLIST_FILE = Source/Info.plist; 382 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 383 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 384 | PRODUCT_BUNDLE_IDENTIFIER = com.example.ViewStyleExample; 385 | PRODUCT_NAME = "$(TARGET_NAME)"; 386 | SWIFT_VERSION = 3.0; 387 | }; 388 | name = Release; 389 | }; 390 | /* End XCBuildConfiguration section */ 391 | 392 | /* Begin XCConfigurationList section */ 393 | E15AF0DC1E41B66E0082C755 /* Build configuration list for PBXProject "ViewStyleExample" */ = { 394 | isa = XCConfigurationList; 395 | buildConfigurations = ( 396 | E15AF0F11E41B66E0082C755 /* Debug */, 397 | E15AF0F21E41B66E0082C755 /* Release */, 398 | ); 399 | defaultConfigurationIsVisible = 0; 400 | defaultConfigurationName = Release; 401 | }; 402 | E15AF0F31E41B66E0082C755 /* Build configuration list for PBXNativeTarget "ViewStyleExample" */ = { 403 | isa = XCConfigurationList; 404 | buildConfigurations = ( 405 | E15AF0F41E41B66E0082C755 /* Debug */, 406 | E15AF0F51E41B66E0082C755 /* Release */, 407 | ); 408 | defaultConfigurationIsVisible = 0; 409 | defaultConfigurationName = Release; 410 | }; 411 | /* End XCConfigurationList section */ 412 | }; 413 | rootObject = E15AF0D91E41B66E0082C755 /* Project object */; 414 | } 415 | -------------------------------------------------------------------------------- /Example/ViewStyleExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Minya 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ViewStyle 2 | 3 | `ViewStyle` provides a CSS-like way to set the style of a view in iOS. 4 | 5 | The general structure of the Web front-end is that HTML is used to organize the basic structure of the view, and CSS is used to set the display style of HTML. In iOS, if you draw the UI with pure code but not Interface Builder, you need to set the view style manually. Just like HTML and CSS, the aim of `ViewStyle` is to separate the view structure and style code. 6 | 7 | # How to use 8 | 9 | Generally, we will set up a `UITableView` as follow: 10 | 11 | ```swift 12 | tableView = UITableView(frame: self.view.bounds) 13 | tableView!.dataSource = self 14 | tableView!.delegate = self 15 | tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell") 16 | 17 | tableView!.rowHeight = 60.0 18 | tableView!.separatorStyle = UITableViewCellSeparatorStyle.singleLine 19 | tableView!.separatorColor = UIColor.lightGray 20 | tableView!.backgroundView = UIView() 21 | tableView!.separatorInset = UIEdgeInsets(top: 10.0, left: 5.0, bottom: 3.0, right: 10.0) 22 | tableView!.cellLayoutMarginsFollowReadableWidth = true 23 | 24 | self.view.addSubview(tableView!) 25 | ``` 26 | 27 | It is a little bit complicated, especially when there are a lot the views to set. In this case, we might consider to separate the code for the style settings. `ViewStyle` provides a `mi_styles` property for the UIView to set some basic style, just like the following way: 28 | 29 | ```swift 30 | class ViewController: UIViewController { 31 | 32 | var tableView: UITableView? 33 | 34 | override func viewDidLoad() { 35 | super.viewDidLoad() 36 | // Do any additional setup after loading the view, typically from a nib. 37 | 38 | // ... 39 | 40 | tableView = UITableView(frame: self.view.bounds) 41 | tableView!.dataSource = self 42 | tableView!.delegate = self 43 | tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell") 44 | 45 | tableView!.mi_styles = self.tableViewStyle 46 | 47 | self.view.addSubview(tableView!) 48 | } 49 | } 50 | 51 | // MARK: - Table View Style 52 | 53 | extension ViewController { 54 | var tableViewStyle: [Property: Any] { 55 | return [ 56 | .rowHeight: 60.0, 57 | .separatorStyle: UITableViewCellSeparatorStyle.singleLine, 58 | .separatorColor: UIColor.lightGray, 59 | .backgroundView: UIView(), 60 | .separatorInset: UIEdgeInsets(top: 10.0, left: 5.0, bottom: 3.0, right: 10.0), 61 | .cellLayoutMarginsFollowReadableWidth: true 62 | ] 63 | } 64 | } 65 | ``` 66 | 67 | There are two ways to define a style: 68 | 69 | * Computing properties of the class 70 | * Global constants 71 | 72 | It is according to the actual situations. 73 | 74 | > Note: If you set multiple `mi_styles` for the same view, and the style has the same property, then the settings will override the previous settings. 75 | 76 | # Problems 77 | 78 | There are some obvious problems in `ViewStyle`: 79 | 80 | 1. It is not used for layout; 81 | 82 | # Install 83 | 84 | ## CocoaPods 85 | 86 | 1. Add `pod 'ViewStyle'` to your Podfile; 87 | 2. Run `pod install` or `pod update`; 88 | 3. `import ViewStyle)` 89 | 90 | # Requirements 91 | 92 | This library requires iOS 8.0+. 93 | 94 | # LICENSE 95 | 96 | ViewStyle is provided under the MIT license. See LICENSE file for details. 97 | 98 | -------------------------------------------------------------------------------- /README.zh-cn.md: -------------------------------------------------------------------------------- 1 | # ViewStyle 2 | 3 | `ViewStyle`提供了一种类似于CSS的方法,来设置iOS中视图的外观样式。 4 | 5 | # 出发点 6 | 7 | Web前端的一般结构是HTML用于组织视图基本结构,而CSS用于设置视图标签的显示样式。在iOS中,如果**用纯代码来手撸界面**的话,也需要我们自己去设置视图元素的各种显示样式。鉴于HTML与CSS的方式的基本思想,`ViewStyle`提供了一种类似的方法,希望将视图的结构与样式设置分离。 8 | 9 | # 基本用法 10 | 11 | 我们以`UITableView`为例,一般我们会按以下方式来设置一个`UITableView`: 12 | 13 | ```swift 14 | tableView = UITableView(frame: self.view.bounds) 15 | tableView!.dataSource = self 16 | tableView!.delegate = self 17 | tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell") 18 | 19 | tableView!.rowHeight = 60.0 20 | tableView!.separatorStyle = UITableViewCellSeparatorStyle.singleLine 21 | tableView!.separatorColor = UIColor.lightGray 22 | tableView!.backgroundView = UIView() 23 | tableView!.separatorInset = UIEdgeInsets(top: 10.0, left: 5.0, bottom: 3.0, right: 10.0) 24 | tableView!.cellLayoutMarginsFollowReadableWidth = true 25 | 26 | self.view.addSubview(tableView!) 27 | ``` 28 | 29 | 这种方式设置一个视图稍微有点繁杂,特别是视图代码多的时候。这种情况下可以考虑将样式设置的代码分离出来。`ViewStyle`为`UIView`提供了一个`mi_styles`计算属性,用于设置一样基本样式,使用方法如下: 30 | 31 | ```swift 32 | class ViewController: UIViewController { 33 | 34 | var tableView: UITableView? 35 | 36 | override func viewDidLoad() { 37 | super.viewDidLoad() 38 | // Do any additional setup after loading the view, typically from a nib. 39 | 40 | // ... 41 | 42 | tableView = UITableView(frame: self.view.bounds) 43 | tableView!.dataSource = self 44 | tableView!.delegate = self 45 | tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell") 46 | 47 | tableView!.mi_styles = self.tableViewStyle 48 | 49 | self.view.addSubview(tableView!) 50 | } 51 | } 52 | 53 | // MARK: - Table View Style 54 | 55 | extension ViewController { 56 | var tableViewStyle: [Property: Any] { 57 | return [ 58 | .rowHeight: 60.0, 59 | .separatorStyle: UITableViewCellSeparatorStyle.singleLine, 60 | .separatorColor: UIColor.lightGray, 61 | .backgroundView: UIView(), 62 | .separatorInset: UIEdgeInsets(top: 10.0, left: 5.0, bottom: 3.0, right: 10.0), 63 | .cellLayoutMarginsFollowReadableWidth: true 64 | ] 65 | } 66 | } 67 | ``` 68 | 69 | style的定义有两种方式:一种是定义成类的计算属性;一种定义成全局常量,方便复用。可以根据实际情况处理。 70 | 71 | > 注:如果对同一个视图设置多个`mi_styles`,且style中有相同的属性,则后面的设置会覆盖前面的设置。 72 | 73 | 74 | # 问题 75 | 76 | 由于这是个写着玩的东西,所以只是设置一些简单的样式属性,所以`ViewStyle`目前存在一些明显的问题: 77 | 78 | 1. 无法设置视图的布局(太复杂),这个需要自行使用`AutoLayout`; 79 | 2. 性能问题待查 80 | 81 | # 安装 82 | 83 | ## CocoaPods 84 | 85 | 1. 在 Podfile 中添加 `pod 'ViewStyle'`; 86 | 2. 执行 `pod install` 或 `pod update`; 87 | 3. 在需要使用的文件中导入`ViewStyle(import ViewStyle)`。 88 | 89 | ## Carthage 90 | 91 | 待添加 92 | 93 | # 系统要求 94 | 95 | 该项目最低支持iOS 8.0。后续考虑加入其它系统的支持。 96 | 97 | # LICENSE 98 | 99 | ViewStyle使用MIT许可证,详情见 LICENSE 文件。 100 | 101 | -------------------------------------------------------------------------------- /Source/Core/Property.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MIProperty.swift 3 | // ViewStyle 4 | // 5 | // Created by Konka on 2017/1/23. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Style Property key 12 | public enum MIProperty: String { 13 | 14 | // MARK: - UIView 15 | case backgroundColor 16 | case isHidden 17 | case alpha 18 | case isOpaque 19 | case tintColor 20 | case tintAdjustmentMode 21 | case clipsToBounds 22 | case clearsContextBeforeDrawing 23 | 24 | // MARK: - CALayer 25 | case layerContentsGravity 26 | case layerOpacity 27 | case layerIsHidden 28 | case layerMasksToBounds 29 | case layerMask 30 | case layerIsDoubleSided 31 | case layerCornerRadius 32 | case layerBorderWidth 33 | case layerBorderColor 34 | case layerBackgroundColor 35 | case layerShadowOpacity 36 | case layerShadowRadius 37 | case layerShadowOffset 38 | case layerShadowColor 39 | case layerShadowPath 40 | case layerAllowsEdgeAntialiasing 41 | case layerAllowsGroupOpacity 42 | 43 | // MARK: - UITextView 44 | case isEditable 45 | case allowsEditingTextAttributes 46 | case isSelectable 47 | case textContainerInset 48 | 49 | // MARK: - UITextField 50 | 51 | case borderStyle 52 | case background 53 | case disabledBackground 54 | case clearButtonMode 55 | case rightViewMode 56 | 57 | // MARK: - UITableView 58 | case rowHeight 59 | case separatorStyle 60 | case separatorColor 61 | case separatorEffect 62 | case backgroundView 63 | case separatorInset 64 | case cellLayoutMarginsFollowReadableWidth 65 | 66 | // MARK: - UISwitch 67 | case onTintColor 68 | case thumbTintColor 69 | case onImage 70 | case offImage 71 | 72 | // MARK: - UIScrollView 73 | case contentSize 74 | case contentInset 75 | case isScrollEnabled 76 | case isDirectionalLockEnabled 77 | case scrollsToTop 78 | case isPagingEnabled 79 | case bounces 80 | case alwaysBounceVertical 81 | case alwaysBounceHorizontal 82 | case indicatorStyle 83 | case scrollIndicatorInsets 84 | case showsHorizontalScrollIndicator 85 | case showsVerticalScrollIndicator 86 | 87 | // MARK: - UILabel 88 | case font 89 | case textColor 90 | case textAlignment 91 | case lineBreakMode 92 | case isEnabled 93 | case adjustsFontSizeToFitWidth 94 | case allowsDefaultTighteningForTruncation 95 | case baselineAdjustment 96 | case minimumScaleFactor 97 | case numberOfLines 98 | case highlightedTextColor 99 | case isHighlighted 100 | case shadowColor 101 | case shadowOffset 102 | 103 | // MARK: - UIImageView 104 | case image 105 | case highlightedImage 106 | case isUserInteractionEnabled 107 | 108 | // MARK: - UIButton 109 | case adjustsImageWhenHighlighted 110 | case adjustsImageWhenDisabled 111 | case showsTouchWhenHighlighted 112 | case contentEdgeInsets 113 | case titleEdgeInsets 114 | case imageEdgeInsets 115 | 116 | case titleColorNormal 117 | case titleColorHightlighted 118 | case titleColorDisabled 119 | case titleColorSelected 120 | 121 | case titleShadowColorNormal 122 | case titleShadowColorHighlighted 123 | case titleShadowColorDisabled 124 | case titleShadowColorSelected 125 | 126 | case backgroundImageNormal 127 | case backgroundImageHighlighted 128 | case backgroundImageDisabled 129 | case backgroundImageSelected 130 | 131 | case imageNormal 132 | case imageHighlighted 133 | case imageDisabled 134 | case imageSelected 135 | } 136 | -------------------------------------------------------------------------------- /Source/Core/UIViewStyle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewStyle.swift 3 | // ViewStyle 4 | // 5 | // Created by Konka on 2017/1/23. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | // MARK: - UIView Extension for setting style properties of UIView 13 | extension UIView { 14 | 15 | // An computed MIProperty to set UIView's style. The MIProperty's getter is just return nil, 16 | // so you can't get the style that you have set with this MIProperty. 17 | public var mi_styles: [MIProperty : Any]? { 18 | 19 | get { 20 | return nil 21 | } 22 | 23 | set { 24 | 25 | guard let styles = newValue, styles.count > 0 else { 26 | return 27 | } 28 | 29 | for (key, value) in styles { 30 | mi_setValue(value, forKey: key.rawValue) 31 | } 32 | } 33 | } 34 | 35 | open func mi_setValue(_ value: Any, forKey key: String) { 36 | 37 | let style = MIProperty(rawValue: key)! 38 | 39 | switch style { 40 | case .backgroundColor: backgroundColor <<< (value as? UIColor) 41 | case .isHidden: isHidden <<< (value as! Bool) 42 | case .alpha: alpha <<< (CGFloat(value as! NSNumber)) 43 | case .isOpaque: isOpaque <<< (value as! Bool) 44 | case .tintColor: tintColor <<< (value as! UIColor) 45 | case .tintAdjustmentMode: tintAdjustmentMode <<< (value as! UIViewTintAdjustmentMode) 46 | case .clipsToBounds: clipsToBounds <<< (value as! Bool) 47 | case .clearsContextBeforeDrawing: clearsContextBeforeDrawing <<< (value as! Bool) 48 | case .layerContentsGravity: layer.contentsGravity <<< (value as! String) 49 | case .layerOpacity: layer.opacity <<< (Float(value as! NSNumber)) 50 | case .layerIsHidden: layer.isHidden <<< (value as! Bool) 51 | case .layerMasksToBounds: layer.masksToBounds <<< (value as! Bool) 52 | case .layerMask: layer.mask <<< (value as? CALayer) 53 | case .layerIsDoubleSided: layer.isDoubleSided <<< (value as! Bool) 54 | case .layerCornerRadius: layer.cornerRadius <<< (CGFloat(value as! NSNumber)) 55 | case .layerBorderWidth: layer.borderWidth <<< (CGFloat(value as! NSNumber)) 56 | case .layerBorderColor: layer.borderColor <<< (value as! CGColor) 57 | case .layerBackgroundColor: layer.backgroundColor <<< (value as! CGColor) 58 | case .layerShadowOpacity: layer.shadowOpacity <<< (Float(value as! NSNumber)) 59 | case .layerShadowRadius: layer.shadowRadius <<< (CGFloat(value as! NSNumber)) 60 | case .layerShadowOffset: layer.shadowOffset <<< (value as! CGSize) 61 | case .layerShadowColor: layer.shadowColor <<< (value as! CGColor) 62 | case .layerShadowPath: layer.shadowPath <<< (value as! CGPath) 63 | case .layerAllowsEdgeAntialiasing: layer.allowsEdgeAntialiasing <<< (value as! Bool) 64 | case .layerAllowsGroupOpacity: layer.allowsGroupOpacity <<< (value as! Bool) 65 | default: () 66 | } 67 | } 68 | } 69 | 70 | // MARK: - Operator 71 | infix operator <<< 72 | 73 | public func <<< (property: inout PropertyType, object: PropertyType?) { 74 | setValue(&property, object: object) 75 | } 76 | 77 | public func <<< (property: inout PropertyType?, object: PropertyType?) { 78 | setValue(&property, object: object) 79 | } 80 | 81 | public func <<< (property: inout PropertyType!, object: PropertyType?) { 82 | setValue(&property, object: object) 83 | } 84 | 85 | // MARK: - Set value 86 | private func setValue(_ property: inout PropertyType, object: PropertyType?) { 87 | if let value = object { 88 | property = value 89 | } 90 | } 91 | 92 | private func setValue(_ property: inout PropertyType?, object: PropertyType?) { 93 | property = object 94 | } 95 | 96 | private func setValue(_ property: inout PropertyType!, object: PropertyType?) { 97 | property = object 98 | } 99 | -------------------------------------------------------------------------------- /Source/Extensions/UIButton+Style.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIButton+Style.swift 3 | // ViewStyle 4 | // 5 | // Created by Konka on 2017/1/25. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension UIButton { 13 | open override func mi_setValue(_ value: Any, forKey key: String) { 14 | let style = MIProperty(rawValue: key)! 15 | 16 | switch style { 17 | case .adjustsImageWhenHighlighted: adjustsImageWhenHighlighted <<< (value as! Bool) 18 | case .adjustsImageWhenDisabled: adjustsImageWhenDisabled <<< (value as! Bool) 19 | case .showsTouchWhenHighlighted: showsTouchWhenHighlighted <<< (value as! Bool) 20 | case .tintColor: tintColor <<< (value as! UIColor) 21 | case .contentEdgeInsets: contentEdgeInsets <<< (value as! UIEdgeInsets) 22 | case .titleEdgeInsets: titleEdgeInsets <<< (value as! UIEdgeInsets) 23 | case .imageEdgeInsets: imageEdgeInsets <<< (value as! UIEdgeInsets) 24 | 25 | case .titleColorNormal: setTitleColor(value as? UIColor, for: .normal) 26 | case .titleColorHightlighted: setTitleColor(value as? UIColor, for: .highlighted) 27 | case .titleColorDisabled: setTitleColor(value as? UIColor, for: .disabled) 28 | case .titleColorSelected: setTitleColor(value as? UIColor, for: .selected) 29 | 30 | case .titleShadowColorNormal: setTitleShadowColor(value as? UIColor, for: .normal) 31 | case .titleShadowColorHighlighted: setTitleShadowColor(value as? UIColor, for: .highlighted) 32 | case .titleShadowColorDisabled: setTitleShadowColor(value as? UIColor, for: .disabled) 33 | case .titleShadowColorSelected: setTitleShadowColor(value as? UIColor, for: .selected) 34 | 35 | case .backgroundImageNormal: setBackgroundImage(value as? UIImage, for: .normal) 36 | case .backgroundImageHighlighted: setBackgroundImage(value as? UIImage, for: .highlighted) 37 | case .backgroundImageDisabled: setBackgroundImage(value as? UIImage, for: .disabled) 38 | case .backgroundImageSelected: setBackgroundImage(value as? UIImage, for: .selected) 39 | 40 | case .imageNormal: setImage(value as? UIImage, for: .normal) 41 | case .imageHighlighted: setImage(value as? UIImage, for: .highlighted) 42 | case .imageDisabled: setImage(value as? UIImage, for: .disabled) 43 | case .imageSelected: setImage(value as? UIImage, for: .selected) 44 | 45 | default: super.mi_setValue(value, forKey: key) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Source/Extensions/UIImageView+Style.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+Style.swift 3 | // ViewStyle 4 | // 5 | // Created by Konka on 2017/1/25. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension UIImageView { 12 | 13 | open override func mi_setValue(_ value: Any, forKey key: String) { 14 | let style = MIProperty(rawValue: key)! 15 | 16 | switch style { 17 | case .image: image <<< (value as? UIImage) 18 | case .highlightedImage: highlightedImage <<< (value as? UIImage) 19 | case .isUserInteractionEnabled: isUserInteractionEnabled <<< (value as! Bool) 20 | case .isHighlighted: isHighlighted <<< (value as! Bool) 21 | case .tintColor: tintColor <<< (value as! UIColor) 22 | default: super.mi_setValue(value, forKey: key) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Source/Extensions/UILabel+Style.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+Style.swift 3 | // ViewStyle 4 | // 5 | // Created by Konka on 2017/1/23. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension UILabel { 13 | 14 | open override func mi_setValue(_ value: Any, forKey key: String) { 15 | let style = MIProperty(rawValue: key)! 16 | 17 | switch style { 18 | case .font: font <<< (value as! UIFont) 19 | case .textColor: textColor <<< (value as! UIColor) 20 | case .textAlignment: textAlignment <<< (value as! NSTextAlignment) 21 | case .lineBreakMode: lineBreakMode <<< (value as! NSLineBreakMode) 22 | case .isEnabled: isEnabled <<< (value as! Bool) 23 | case .adjustsFontSizeToFitWidth: adjustsFontSizeToFitWidth <<< (value as! Bool) 24 | case .baselineAdjustment: baselineAdjustment <<< (value as! UIBaselineAdjustment) 25 | case .minimumScaleFactor: minimumScaleFactor <<< (CGFloat(value as! NSNumber)) 26 | case .numberOfLines: numberOfLines <<< (Int(value as! NSNumber)) 27 | case .highlightedTextColor: highlightedTextColor <<< (value as? UIColor) 28 | case .isHighlighted: isHighlighted <<< (value as! Bool) 29 | case .shadowColor: shadowColor <<< (value as? UIColor) 30 | case .shadowOffset: shadowOffset <<< (value as! CGSize) 31 | case .allowsDefaultTighteningForTruncation: 32 | if #available(iOS 9.0, *) { 33 | allowsDefaultTighteningForTruncation <<< (value as! Bool) 34 | } 35 | default: super.mi_setValue(value, forKey: key) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/Extensions/UIScrollView+Style.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+Style.swift 3 | // ViewStyle 4 | // 5 | // Created by Konka on 2017/1/24. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension UIScrollView { 13 | 14 | open override func mi_setValue(_ value: Any, forKey key: String) { 15 | let style = MIProperty(rawValue: key)! 16 | 17 | switch style { 18 | case .contentSize: contentSize <<< (value as! CGSize) 19 | case .contentInset: contentInset <<< (value as! UIEdgeInsets) 20 | case .isScrollEnabled: isScrollEnabled <<< (value as! Bool) 21 | case .isDirectionalLockEnabled: isDirectionalLockEnabled <<< (value as! Bool) 22 | case .scrollsToTop: scrollsToTop <<< (value as! Bool) 23 | case .isPagingEnabled: isPagingEnabled <<< (value as! Bool) 24 | case .bounces: bounces <<< (value as! Bool) 25 | case .alwaysBounceVertical: alwaysBounceVertical <<< (value as! Bool) 26 | case .alwaysBounceHorizontal: alwaysBounceHorizontal <<< (value as! Bool) 27 | case .indicatorStyle: indicatorStyle <<< (value as! UIScrollViewIndicatorStyle) 28 | case .scrollIndicatorInsets: scrollIndicatorInsets <<< (value as! UIEdgeInsets) 29 | case .showsVerticalScrollIndicator: showsVerticalScrollIndicator <<< (value as! Bool) 30 | case .showsHorizontalScrollIndicator: showsHorizontalScrollIndicator <<< (value as! Bool) 31 | default: super.mi_setValue(value, forKey: key) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Source/Extensions/UISwitch+Style.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UISwitch+Style.swift 3 | // ViewStyle 4 | // 5 | // Created by Konka on 2017/1/24. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension UISwitch { 13 | 14 | open override func mi_setValue(_ value: Any, forKey key: String) { 15 | let style = MIProperty(rawValue: key)! 16 | 17 | switch style { 18 | case .onTintColor: onTintColor <<< (value as? UIColor) 19 | case .tintColor: tintColor <<< (value as! UIColor) 20 | case .thumbTintColor: thumbTintColor <<< (value as? UIColor) 21 | case .onImage: onImage <<< (value as? UIImage) 22 | case .offImage: offImage <<< (value as? UIImage) 23 | default: super.mi_setValue(value, forKey: key) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Source/Extensions/UITableView+Style.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+Style.swift 3 | // ViewStyle 4 | // 5 | // Created by Konka on 2017/1/25. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension UITableView { 13 | 14 | open override func mi_setValue(_ value: Any, forKey key: String) { 15 | let style = MIProperty(rawValue: key)! 16 | 17 | switch style { 18 | case .rowHeight: rowHeight <<< (CGFloat(value as! NSNumber)) 19 | case .separatorStyle: separatorStyle <<< (value as! UITableViewCellSeparatorStyle) 20 | case .separatorColor: separatorColor <<< (value as? UIColor) 21 | case .separatorEffect: separatorEffect <<< (value as? UIVisualEffect) 22 | case .backgroundView: backgroundView <<< (value as? UIView) 23 | case .separatorInset: separatorInset <<< (value as! UIEdgeInsets) 24 | case .cellLayoutMarginsFollowReadableWidth: 25 | if #available(iOS 9.0, *) { 26 | cellLayoutMarginsFollowReadableWidth <<< (value as! Bool) 27 | } 28 | default: super.mi_setValue(value, forKey: key) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Source/Extensions/UITextField+Style.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+Style.swift 3 | // ViewStyle 4 | // 5 | // Created by Konka on 2017/1/25. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension UITextField { 13 | 14 | open override func mi_setValue(_ value: Any, forKey key: String) { 15 | let style = MIProperty(rawValue: key)! 16 | 17 | switch style { 18 | case .font: font <<< (value as? UIFont) 19 | case .textColor: textColor <<< (value as? UIColor) 20 | case .textAlignment: textAlignment <<< (value as! NSTextAlignment) 21 | case .borderStyle: borderStyle <<< (value as! UITextBorderStyle) 22 | case .background: background <<< (value as? UIImage) 23 | case .disabledBackground: disabledBackground <<< (value as? UIImage) 24 | case .clearButtonMode: clearButtonMode <<< (value as! UITextFieldViewMode) 25 | case .rightViewMode: rightViewMode <<< (value as! UITextFieldViewMode) 26 | default: super.mi_setValue(value, forKey: key) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Source/Extensions/UITextView+Style.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UITextView+Style.swift 3 | // ViewStyle 4 | // 5 | // Created by Konka on 2017/1/25. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension UITextView { 13 | 14 | open override func mi_setValue(_ value: Any, forKey key: String) { 15 | 16 | let style = MIProperty(rawValue: key)! 17 | 18 | switch style { 19 | case .font: font <<< (value as? UIFont) 20 | case .textColor: textColor <<< (value as? UIColor) 21 | case .isEditable: isEditable <<< (value as! Bool) 22 | case .allowsEditingTextAttributes: allowsEditingTextAttributes <<< (value as! Bool) 23 | case .textAlignment: textAlignment <<< (value as! NSTextAlignment) 24 | case .textContainerInset: textContainerInset <<< (value as! UIEdgeInsets) 25 | case .isSelectable: isSelectable <<< (value as! Bool) 26 | default: super.mi_setValue(value, forKey: key) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Source/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Source/ViewStyle.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewStyle.h 3 | // ViewStyle 4 | // 5 | // Created by Konka on 2017/2/1. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for ViewStyle. 12 | FOUNDATION_EXPORT double ViewStyleVersionNumber; 13 | 14 | //! Project version string for ViewStyle. 15 | FOUNDATION_EXPORT const unsigned char ViewStyleVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tests.swift 3 | // Tests 4 | // 5 | // Created by Konka on 2017/2/1. 6 | // Copyright © 2017年 Minya. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import ViewStyle 11 | 12 | class Tests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /ViewStyle.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | 4 | s.name = "ViewStyle" 5 | s.version = "1.0.0" 6 | s.summary = "Provides a way to set UIView's visual appearance properties like CSS" 7 | s.homepage = "https://github.com/southpeak/ViewStyle" 8 | s.license = "MIT" 9 | 10 | s.author = "Minya" 11 | s.social_media_url = "http://weibo.com/touristdiary" 12 | 13 | s.source = { :git => "https://github.com/southpeak/ViewStyle.git", :tag => "#{s.version}" } 14 | 15 | s.ios.deployment_target = '8.0' 16 | 17 | # s.source_files = "Source/*.swift" 18 | 19 | s.subspec 'Core' do |core| 20 | core.source_files = "Source/Core" 21 | end 22 | 23 | s.subspec 'Extensions' do |ex| 24 | ex.source_files = "Source/Extensions" 25 | ex.dependency "ViewStyle/Core" 26 | end 27 | 28 | end 29 | -------------------------------------------------------------------------------- /ViewStyle.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E15AF0CB1E41B5480082C755 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF0CA1E41B5480082C755 /* Tests.swift */; }; 11 | E15AF0CD1E41B5480082C755 /* ViewStyle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E15AF0AA1E41B4A80082C755 /* ViewStyle.framework */; }; 12 | E15AF0D71E41B58D0082C755 /* ViewStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = E15AF0D51E41B58D0082C755 /* ViewStyle.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | E15AF1181E41BAFB0082C755 /* Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF1091E41BAFB0082C755 /* Property.swift */; }; 14 | E15AF1191E41BAFB0082C755 /* UIViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF10A1E41BAFB0082C755 /* UIViewStyle.swift */; }; 15 | E15AF11A1E41BAFB0082C755 /* UIButton+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF10C1E41BAFB0082C755 /* UIButton+Style.swift */; }; 16 | E15AF11D1E41BAFB0082C755 /* UIImageView+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF10F1E41BAFB0082C755 /* UIImageView+Style.swift */; }; 17 | E15AF11E1E41BAFB0082C755 /* UILabel+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF1101E41BAFB0082C755 /* UILabel+Style.swift */; }; 18 | E15AF11F1E41BAFB0082C755 /* UIScrollView+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF1111E41BAFB0082C755 /* UIScrollView+Style.swift */; }; 19 | E15AF1201E41BAFB0082C755 /* UISwitch+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF1121E41BAFB0082C755 /* UISwitch+Style.swift */; }; 20 | E15AF1211E41BAFB0082C755 /* UITableView+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF1131E41BAFB0082C755 /* UITableView+Style.swift */; }; 21 | E15AF1221E41BAFB0082C755 /* UITextField+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF1141E41BAFB0082C755 /* UITextField+Style.swift */; }; 22 | E15AF1231E41BAFB0082C755 /* UITextView+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15AF1151E41BAFB0082C755 /* UITextView+Style.swift */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | E15AF0CE1E41B5480082C755 /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = E15AF0A11E41B4A80082C755 /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = E15AF0A91E41B4A80082C755; 31 | remoteInfo = ViewStyle; 32 | }; 33 | /* End PBXContainerItemProxy section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | E15AF0AA1E41B4A80082C755 /* ViewStyle.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ViewStyle.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | E15AF0C81E41B5480082C755 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | E15AF0CA1E41B5480082C755 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 39 | E15AF0CC1E41B5480082C755 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 40 | E15AF0D41E41B58D0082C755 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | E15AF0D51E41B58D0082C755 /* ViewStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewStyle.h; sourceTree = ""; }; 42 | E15AF1091E41BAFB0082C755 /* Property.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Property.swift; sourceTree = ""; }; 43 | E15AF10A1E41BAFB0082C755 /* UIViewStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewStyle.swift; sourceTree = ""; }; 44 | E15AF10C1E41BAFB0082C755 /* UIButton+Style.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIButton+Style.swift"; sourceTree = ""; }; 45 | E15AF10F1E41BAFB0082C755 /* UIImageView+Style.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImageView+Style.swift"; sourceTree = ""; }; 46 | E15AF1101E41BAFB0082C755 /* UILabel+Style.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UILabel+Style.swift"; sourceTree = ""; }; 47 | E15AF1111E41BAFB0082C755 /* UIScrollView+Style.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIScrollView+Style.swift"; sourceTree = ""; }; 48 | E15AF1121E41BAFB0082C755 /* UISwitch+Style.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UISwitch+Style.swift"; sourceTree = ""; }; 49 | E15AF1131E41BAFB0082C755 /* UITableView+Style.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+Style.swift"; sourceTree = ""; }; 50 | E15AF1141E41BAFB0082C755 /* UITextField+Style.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITextField+Style.swift"; sourceTree = ""; }; 51 | E15AF1151E41BAFB0082C755 /* UITextView+Style.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITextView+Style.swift"; sourceTree = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | E15AF0A61E41B4A80082C755 /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | E15AF0C51E41B5480082C755 /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | E15AF0CD1E41B5480082C755 /* ViewStyle.framework in Frameworks */, 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXFrameworksBuildPhase section */ 71 | 72 | /* Begin PBXGroup section */ 73 | E15AF0A01E41B4A80082C755 = { 74 | isa = PBXGroup; 75 | children = ( 76 | E15AF0D31E41B58D0082C755 /* Source */, 77 | E15AF0C91E41B5480082C755 /* Tests */, 78 | E15AF0AB1E41B4A80082C755 /* Products */, 79 | ); 80 | sourceTree = ""; 81 | }; 82 | E15AF0AB1E41B4A80082C755 /* Products */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | E15AF0AA1E41B4A80082C755 /* ViewStyle.framework */, 86 | E15AF0C81E41B5480082C755 /* Tests.xctest */, 87 | ); 88 | name = Products; 89 | sourceTree = ""; 90 | }; 91 | E15AF0C91E41B5480082C755 /* Tests */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | E15AF0CA1E41B5480082C755 /* Tests.swift */, 95 | E15AF0CC1E41B5480082C755 /* Info.plist */, 96 | ); 97 | path = Tests; 98 | sourceTree = ""; 99 | }; 100 | E15AF0D31E41B58D0082C755 /* Source */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | E15AF1071E41BAFB0082C755 /* Core */, 104 | E15AF10B1E41BAFB0082C755 /* Extensions */, 105 | E15AF0D41E41B58D0082C755 /* Info.plist */, 106 | E15AF0D51E41B58D0082C755 /* ViewStyle.h */, 107 | ); 108 | path = Source; 109 | sourceTree = ""; 110 | }; 111 | E15AF1071E41BAFB0082C755 /* Core */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | E15AF1091E41BAFB0082C755 /* Property.swift */, 115 | E15AF10A1E41BAFB0082C755 /* UIViewStyle.swift */, 116 | ); 117 | path = Core; 118 | sourceTree = ""; 119 | }; 120 | E15AF10B1E41BAFB0082C755 /* Extensions */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | E15AF10C1E41BAFB0082C755 /* UIButton+Style.swift */, 124 | E15AF10F1E41BAFB0082C755 /* UIImageView+Style.swift */, 125 | E15AF1101E41BAFB0082C755 /* UILabel+Style.swift */, 126 | E15AF1111E41BAFB0082C755 /* UIScrollView+Style.swift */, 127 | E15AF1121E41BAFB0082C755 /* UISwitch+Style.swift */, 128 | E15AF1131E41BAFB0082C755 /* UITableView+Style.swift */, 129 | E15AF1141E41BAFB0082C755 /* UITextField+Style.swift */, 130 | E15AF1151E41BAFB0082C755 /* UITextView+Style.swift */, 131 | ); 132 | path = Extensions; 133 | sourceTree = ""; 134 | }; 135 | /* End PBXGroup section */ 136 | 137 | /* Begin PBXHeadersBuildPhase section */ 138 | E15AF0A71E41B4A80082C755 /* Headers */ = { 139 | isa = PBXHeadersBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | E15AF0D71E41B58D0082C755 /* ViewStyle.h in Headers */, 143 | ); 144 | runOnlyForDeploymentPostprocessing = 0; 145 | }; 146 | /* End PBXHeadersBuildPhase section */ 147 | 148 | /* Begin PBXNativeTarget section */ 149 | E15AF0A91E41B4A80082C755 /* ViewStyle */ = { 150 | isa = PBXNativeTarget; 151 | buildConfigurationList = E15AF0BE1E41B4A80082C755 /* Build configuration list for PBXNativeTarget "ViewStyle" */; 152 | buildPhases = ( 153 | E15AF0A51E41B4A80082C755 /* Sources */, 154 | E15AF0A61E41B4A80082C755 /* Frameworks */, 155 | E15AF0A71E41B4A80082C755 /* Headers */, 156 | E15AF0A81E41B4A80082C755 /* Resources */, 157 | ); 158 | buildRules = ( 159 | ); 160 | dependencies = ( 161 | ); 162 | name = ViewStyle; 163 | productName = ViewStyle; 164 | productReference = E15AF0AA1E41B4A80082C755 /* ViewStyle.framework */; 165 | productType = "com.apple.product-type.framework"; 166 | }; 167 | E15AF0C71E41B5480082C755 /* Tests */ = { 168 | isa = PBXNativeTarget; 169 | buildConfigurationList = E15AF0D01E41B5480082C755 /* Build configuration list for PBXNativeTarget "Tests" */; 170 | buildPhases = ( 171 | E15AF0C41E41B5480082C755 /* Sources */, 172 | E15AF0C51E41B5480082C755 /* Frameworks */, 173 | E15AF0C61E41B5480082C755 /* Resources */, 174 | ); 175 | buildRules = ( 176 | ); 177 | dependencies = ( 178 | E15AF0CF1E41B5480082C755 /* PBXTargetDependency */, 179 | ); 180 | name = Tests; 181 | productName = Tests; 182 | productReference = E15AF0C81E41B5480082C755 /* Tests.xctest */; 183 | productType = "com.apple.product-type.bundle.unit-test"; 184 | }; 185 | /* End PBXNativeTarget section */ 186 | 187 | /* Begin PBXProject section */ 188 | E15AF0A11E41B4A80082C755 /* Project object */ = { 189 | isa = PBXProject; 190 | attributes = { 191 | LastSwiftUpdateCheck = 0820; 192 | LastUpgradeCheck = 0820; 193 | ORGANIZATIONNAME = Minya; 194 | TargetAttributes = { 195 | E15AF0A91E41B4A80082C755 = { 196 | CreatedOnToolsVersion = 8.2.1; 197 | ProvisioningStyle = Automatic; 198 | }; 199 | E15AF0C71E41B5480082C755 = { 200 | CreatedOnToolsVersion = 8.2.1; 201 | ProvisioningStyle = Automatic; 202 | }; 203 | }; 204 | }; 205 | buildConfigurationList = E15AF0A41E41B4A80082C755 /* Build configuration list for PBXProject "ViewStyle" */; 206 | compatibilityVersion = "Xcode 3.2"; 207 | developmentRegion = English; 208 | hasScannedForEncodings = 0; 209 | knownRegions = ( 210 | en, 211 | ); 212 | mainGroup = E15AF0A01E41B4A80082C755; 213 | productRefGroup = E15AF0AB1E41B4A80082C755 /* Products */; 214 | projectDirPath = ""; 215 | projectRoot = ""; 216 | targets = ( 217 | E15AF0A91E41B4A80082C755 /* ViewStyle */, 218 | E15AF0C71E41B5480082C755 /* Tests */, 219 | ); 220 | }; 221 | /* End PBXProject section */ 222 | 223 | /* Begin PBXResourcesBuildPhase section */ 224 | E15AF0A81E41B4A80082C755 /* Resources */ = { 225 | isa = PBXResourcesBuildPhase; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | ); 229 | runOnlyForDeploymentPostprocessing = 0; 230 | }; 231 | E15AF0C61E41B5480082C755 /* Resources */ = { 232 | isa = PBXResourcesBuildPhase; 233 | buildActionMask = 2147483647; 234 | files = ( 235 | ); 236 | runOnlyForDeploymentPostprocessing = 0; 237 | }; 238 | /* End PBXResourcesBuildPhase section */ 239 | 240 | /* Begin PBXSourcesBuildPhase section */ 241 | E15AF0A51E41B4A80082C755 /* Sources */ = { 242 | isa = PBXSourcesBuildPhase; 243 | buildActionMask = 2147483647; 244 | files = ( 245 | E15AF11E1E41BAFB0082C755 /* UILabel+Style.swift in Sources */, 246 | E15AF1201E41BAFB0082C755 /* UISwitch+Style.swift in Sources */, 247 | E15AF1191E41BAFB0082C755 /* UIViewStyle.swift in Sources */, 248 | E15AF11F1E41BAFB0082C755 /* UIScrollView+Style.swift in Sources */, 249 | E15AF11A1E41BAFB0082C755 /* UIButton+Style.swift in Sources */, 250 | E15AF1181E41BAFB0082C755 /* Property.swift in Sources */, 251 | E15AF1221E41BAFB0082C755 /* UITextField+Style.swift in Sources */, 252 | E15AF1211E41BAFB0082C755 /* UITableView+Style.swift in Sources */, 253 | E15AF11D1E41BAFB0082C755 /* UIImageView+Style.swift in Sources */, 254 | E15AF1231E41BAFB0082C755 /* UITextView+Style.swift in Sources */, 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | }; 258 | E15AF0C41E41B5480082C755 /* Sources */ = { 259 | isa = PBXSourcesBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | E15AF0CB1E41B5480082C755 /* Tests.swift in Sources */, 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | /* End PBXSourcesBuildPhase section */ 267 | 268 | /* Begin PBXTargetDependency section */ 269 | E15AF0CF1E41B5480082C755 /* PBXTargetDependency */ = { 270 | isa = PBXTargetDependency; 271 | target = E15AF0A91E41B4A80082C755 /* ViewStyle */; 272 | targetProxy = E15AF0CE1E41B5480082C755 /* PBXContainerItemProxy */; 273 | }; 274 | /* End PBXTargetDependency section */ 275 | 276 | /* Begin XCBuildConfiguration section */ 277 | E15AF0BC1E41B4A80082C755 /* Debug */ = { 278 | isa = XCBuildConfiguration; 279 | buildSettings = { 280 | ALWAYS_SEARCH_USER_PATHS = NO; 281 | CLANG_ANALYZER_NONNULL = YES; 282 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 283 | CLANG_CXX_LIBRARY = "libc++"; 284 | CLANG_ENABLE_MODULES = YES; 285 | CLANG_ENABLE_OBJC_ARC = YES; 286 | CLANG_WARN_BOOL_CONVERSION = YES; 287 | CLANG_WARN_CONSTANT_CONVERSION = YES; 288 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 289 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 290 | CLANG_WARN_EMPTY_BODY = YES; 291 | CLANG_WARN_ENUM_CONVERSION = YES; 292 | CLANG_WARN_INFINITE_RECURSION = YES; 293 | CLANG_WARN_INT_CONVERSION = YES; 294 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 295 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 296 | CLANG_WARN_UNREACHABLE_CODE = YES; 297 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 298 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 299 | COPY_PHASE_STRIP = NO; 300 | CURRENT_PROJECT_VERSION = 1; 301 | DEBUG_INFORMATION_FORMAT = dwarf; 302 | ENABLE_STRICT_OBJC_MSGSEND = YES; 303 | ENABLE_TESTABILITY = YES; 304 | GCC_C_LANGUAGE_STANDARD = gnu99; 305 | GCC_DYNAMIC_NO_PIC = NO; 306 | GCC_NO_COMMON_BLOCKS = YES; 307 | GCC_OPTIMIZATION_LEVEL = 0; 308 | GCC_PREPROCESSOR_DEFINITIONS = ( 309 | "DEBUG=1", 310 | "$(inherited)", 311 | ); 312 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 313 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 314 | GCC_WARN_UNDECLARED_SELECTOR = YES; 315 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 316 | GCC_WARN_UNUSED_FUNCTION = YES; 317 | GCC_WARN_UNUSED_VARIABLE = YES; 318 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 319 | MTL_ENABLE_DEBUG_INFO = YES; 320 | ONLY_ACTIVE_ARCH = YES; 321 | SDKROOT = iphoneos; 322 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 323 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 324 | TARGETED_DEVICE_FAMILY = "1,2"; 325 | VERSIONING_SYSTEM = "apple-generic"; 326 | VERSION_INFO_PREFIX = ""; 327 | }; 328 | name = Debug; 329 | }; 330 | E15AF0BD1E41B4A80082C755 /* Release */ = { 331 | isa = XCBuildConfiguration; 332 | buildSettings = { 333 | ALWAYS_SEARCH_USER_PATHS = NO; 334 | CLANG_ANALYZER_NONNULL = YES; 335 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 336 | CLANG_CXX_LIBRARY = "libc++"; 337 | CLANG_ENABLE_MODULES = YES; 338 | CLANG_ENABLE_OBJC_ARC = YES; 339 | CLANG_WARN_BOOL_CONVERSION = YES; 340 | CLANG_WARN_CONSTANT_CONVERSION = YES; 341 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 342 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 343 | CLANG_WARN_EMPTY_BODY = YES; 344 | CLANG_WARN_ENUM_CONVERSION = YES; 345 | CLANG_WARN_INFINITE_RECURSION = YES; 346 | CLANG_WARN_INT_CONVERSION = YES; 347 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 348 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 349 | CLANG_WARN_UNREACHABLE_CODE = YES; 350 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 351 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 352 | COPY_PHASE_STRIP = NO; 353 | CURRENT_PROJECT_VERSION = 1; 354 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 355 | ENABLE_NS_ASSERTIONS = NO; 356 | ENABLE_STRICT_OBJC_MSGSEND = YES; 357 | GCC_C_LANGUAGE_STANDARD = gnu99; 358 | GCC_NO_COMMON_BLOCKS = YES; 359 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 360 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 361 | GCC_WARN_UNDECLARED_SELECTOR = YES; 362 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 363 | GCC_WARN_UNUSED_FUNCTION = YES; 364 | GCC_WARN_UNUSED_VARIABLE = YES; 365 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 366 | MTL_ENABLE_DEBUG_INFO = NO; 367 | SDKROOT = iphoneos; 368 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 369 | TARGETED_DEVICE_FAMILY = "1,2"; 370 | VALIDATE_PRODUCT = YES; 371 | VERSIONING_SYSTEM = "apple-generic"; 372 | VERSION_INFO_PREFIX = ""; 373 | }; 374 | name = Release; 375 | }; 376 | E15AF0BF1E41B4A80082C755 /* Debug */ = { 377 | isa = XCBuildConfiguration; 378 | buildSettings = { 379 | CODE_SIGN_IDENTITY = ""; 380 | DEFINES_MODULE = YES; 381 | DEVELOPMENT_TEAM = ""; 382 | DYLIB_COMPATIBILITY_VERSION = 1; 383 | DYLIB_CURRENT_VERSION = 1; 384 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 385 | INFOPLIST_FILE = Source/Info.plist; 386 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 387 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 388 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 389 | PRODUCT_BUNDLE_IDENTIFIER = com.ios.ViewStyle; 390 | PRODUCT_NAME = "$(TARGET_NAME)"; 391 | SKIP_INSTALL = YES; 392 | SWIFT_VERSION = 3.0; 393 | TARGETED_DEVICE_FAMILY = "1,2"; 394 | }; 395 | name = Debug; 396 | }; 397 | E15AF0C01E41B4A80082C755 /* Release */ = { 398 | isa = XCBuildConfiguration; 399 | buildSettings = { 400 | CODE_SIGN_IDENTITY = ""; 401 | DEFINES_MODULE = YES; 402 | DEVELOPMENT_TEAM = ""; 403 | DYLIB_COMPATIBILITY_VERSION = 1; 404 | DYLIB_CURRENT_VERSION = 1; 405 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 406 | INFOPLIST_FILE = Source/Info.plist; 407 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 408 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 409 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 410 | PRODUCT_BUNDLE_IDENTIFIER = com.ios.ViewStyle; 411 | PRODUCT_NAME = "$(TARGET_NAME)"; 412 | SKIP_INSTALL = YES; 413 | SWIFT_VERSION = 3.0; 414 | TARGETED_DEVICE_FAMILY = "1,2"; 415 | }; 416 | name = Release; 417 | }; 418 | E15AF0D11E41B5480082C755 /* Debug */ = { 419 | isa = XCBuildConfiguration; 420 | buildSettings = { 421 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 422 | DEVELOPMENT_TEAM = ""; 423 | INFOPLIST_FILE = Tests/Info.plist; 424 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 425 | PRODUCT_BUNDLE_IDENTIFIER = com.xmu.Tests; 426 | PRODUCT_NAME = "$(TARGET_NAME)"; 427 | SWIFT_VERSION = 3.0; 428 | }; 429 | name = Debug; 430 | }; 431 | E15AF0D21E41B5480082C755 /* Release */ = { 432 | isa = XCBuildConfiguration; 433 | buildSettings = { 434 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 435 | DEVELOPMENT_TEAM = ""; 436 | INFOPLIST_FILE = Tests/Info.plist; 437 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 438 | PRODUCT_BUNDLE_IDENTIFIER = com.xmu.Tests; 439 | PRODUCT_NAME = "$(TARGET_NAME)"; 440 | SWIFT_VERSION = 3.0; 441 | }; 442 | name = Release; 443 | }; 444 | /* End XCBuildConfiguration section */ 445 | 446 | /* Begin XCConfigurationList section */ 447 | E15AF0A41E41B4A80082C755 /* Build configuration list for PBXProject "ViewStyle" */ = { 448 | isa = XCConfigurationList; 449 | buildConfigurations = ( 450 | E15AF0BC1E41B4A80082C755 /* Debug */, 451 | E15AF0BD1E41B4A80082C755 /* Release */, 452 | ); 453 | defaultConfigurationIsVisible = 0; 454 | defaultConfigurationName = Release; 455 | }; 456 | E15AF0BE1E41B4A80082C755 /* Build configuration list for PBXNativeTarget "ViewStyle" */ = { 457 | isa = XCConfigurationList; 458 | buildConfigurations = ( 459 | E15AF0BF1E41B4A80082C755 /* Debug */, 460 | E15AF0C01E41B4A80082C755 /* Release */, 461 | ); 462 | defaultConfigurationIsVisible = 0; 463 | defaultConfigurationName = Release; 464 | }; 465 | E15AF0D01E41B5480082C755 /* Build configuration list for PBXNativeTarget "Tests" */ = { 466 | isa = XCConfigurationList; 467 | buildConfigurations = ( 468 | E15AF0D11E41B5480082C755 /* Debug */, 469 | E15AF0D21E41B5480082C755 /* Release */, 470 | ); 471 | defaultConfigurationIsVisible = 0; 472 | defaultConfigurationName = Release; 473 | }; 474 | /* End XCConfigurationList section */ 475 | }; 476 | rootObject = E15AF0A11E41B4A80082C755 /* Project object */; 477 | } 478 | -------------------------------------------------------------------------------- /ViewStyle.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ViewStyle.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | --------------------------------------------------------------------------------