├── IMG_1636.PNG
├── IMG_1637.PNG
├── IMG_1638.PNG
├── Kgif.gif
├── README.md
├── SkfSwiftCammer-Prefix.pch
├── SkfSwiftCammer.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── xcuserdata
│ └── Kevin.xcuserdatad
│ └── xcschemes
│ ├── SkfSwiftCammer.xcscheme
│ └── xcschememanagement.plist
├── SkfSwiftCammer
├── ALCameraViewController
│ ├── ALCameraViewAssets.xcassets
│ │ ├── ALPlaceholder.imageset
│ │ │ ├── Contents.json
│ │ │ ├── placeholder.png
│ │ │ ├── placeholder@2x.png
│ │ │ └── placeholder@3x.png
│ │ ├── Contents.json
│ │ ├── cameraButton.imageset
│ │ │ ├── Contents.json
│ │ │ ├── cameraButton.png
│ │ │ ├── cameraButton@2x.png
│ │ │ └── cameraButton@3x.png
│ │ ├── cameraButtonHighlighted.imageset
│ │ │ ├── Contents.json
│ │ │ ├── cameraButtonHighlighted.png
│ │ │ ├── cameraButtonHighlighted@2x.png
│ │ │ └── cameraButtonHighlighted@3x.png
│ │ ├── closeButton.imageset
│ │ │ ├── Contents.json
│ │ │ ├── closeButton.png
│ │ │ ├── closeButton@2x.png
│ │ │ └── closeButton@3x.png
│ │ ├── confirmButton.imageset
│ │ │ ├── Contents.json
│ │ │ ├── confirmButton.png
│ │ │ ├── confirmButton@2x.png
│ │ │ └── confirmButton@3x.png
│ │ ├── flashAutoIcon.imageset
│ │ │ ├── Contents.json
│ │ │ ├── flashAutoIcon.png
│ │ │ ├── flashAutoIcon@2x.png
│ │ │ └── flashAutoIcon@3x.png
│ │ ├── flashOffIcon.imageset
│ │ │ ├── Contents.json
│ │ │ ├── flashOffIcon.png
│ │ │ ├── flashOffIcon@2x.png
│ │ │ └── flashOffIcon@3x.png
│ │ ├── flashOnIcon.imageset
│ │ │ ├── Contents.json
│ │ │ ├── flashOnIcon.png
│ │ │ ├── flashOnIcon@2x.png
│ │ │ └── flashOnIcon@3x.png
│ │ ├── libraryButton.imageset
│ │ │ ├── Contents.json
│ │ │ ├── libraryButton.png
│ │ │ ├── libraryButton@2x.png
│ │ │ └── libraryButton@3x.png
│ │ ├── libraryCancel.imageset
│ │ │ ├── Contents.json
│ │ │ ├── libraryCancel.png
│ │ │ ├── libraryCancel@2x.png
│ │ │ └── libraryCancel@3x.png
│ │ ├── libraryConfirm.imageset
│ │ │ ├── Contents.json
│ │ │ ├── libraryConfirm.png
│ │ │ ├── libraryConfirm@2x.png
│ │ │ └── libraryConfirm@3x.png
│ │ ├── permissionsIcon.imageset
│ │ │ ├── Contents.json
│ │ │ ├── cameraPermissionsIcon.png
│ │ │ ├── cameraPermissionsIcon@2x.png
│ │ │ └── cameraPermissionsIcon@3x.png
│ │ ├── retakeButton.imageset
│ │ │ ├── Contents.json
│ │ │ ├── retakeButton.png
│ │ │ ├── retakeButton@2x.png
│ │ │ └── retakeButton@3x.png
│ │ └── swapButton.imageset
│ │ │ ├── Contents.json
│ │ │ ├── swapButton.png
│ │ │ ├── swapButton@2x.png
│ │ │ └── swapButton@3x.png
│ ├── CameraView.strings
│ ├── Utilities
│ │ ├── CameraGlobals.swift
│ │ ├── CameraShot.swift
│ │ ├── ImageExtensions.swift
│ │ ├── ImageFetcher.swift
│ │ ├── PhotoLibraryAuthorizer.swift
│ │ ├── SingleImageFetcher.swift
│ │ ├── SingleImageSaver.swift
│ │ ├── UIButtonExtensions.swift
│ │ ├── Utilities.swift
│ │ └── VolumeControl.swift
│ ├── ViewController
│ │ ├── ALCameraViewController-Bridging-Header.h
│ │ ├── ALCameraViewController.swift
│ │ ├── ConfirmViewController.swift
│ │ ├── ConfirmViewController.xib
│ │ └── PhotoLibraryViewController.swift
│ └── Views
│ │ ├── CameraView.swift
│ │ ├── CropOverlay.swift
│ │ ├── ImageCell.swift
│ │ └── PermissionsView.swift
├── AppDelegate.h
├── AppDelegate.m
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── Info.plist
├── Masonry
│ ├── Info.plist
│ ├── MASCompositeConstraint.h
│ ├── MASCompositeConstraint.m
│ ├── MASConstraint+Private.h
│ ├── MASConstraint.h
│ ├── MASConstraint.m
│ ├── MASConstraintMaker.h
│ ├── MASConstraintMaker.m
│ ├── MASLayoutConstraint.h
│ ├── MASLayoutConstraint.m
│ ├── MASUtilities.h
│ ├── MASViewAttribute.h
│ ├── MASViewAttribute.m
│ ├── MASViewConstraint.h
│ ├── MASViewConstraint.m
│ ├── Masonry.h
│ ├── NSArray+MASAdditions.h
│ ├── NSArray+MASAdditions.m
│ ├── NSArray+MASShorthandAdditions.h
│ ├── NSLayoutConstraint+MASDebugAdditions.h
│ ├── NSLayoutConstraint+MASDebugAdditions.m
│ ├── View+MASAdditions.h
│ ├── View+MASAdditions.m
│ ├── View+MASShorthandAdditions.h
│ ├── ViewController+MASAdditions.h
│ └── ViewController+MASAdditions.m
├── ViewController.h
├── ViewController.m
└── main.m
├── SkfSwiftCammerTests
├── Info.plist
└── SkfSwiftCammerTests.m
└── SkfSwiftCammerUITests
├── Info.plist
└── SkfSwiftCammerUITests.m
/IMG_1636.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/IMG_1636.PNG
--------------------------------------------------------------------------------
/IMG_1637.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/IMG_1637.PNG
--------------------------------------------------------------------------------
/IMG_1638.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/IMG_1638.PNG
--------------------------------------------------------------------------------
/Kgif.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/Kgif.gif
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #### 微博 敲代码的手艺人
2 | ##### [Blog地址](http://www.cnblogs.com/sunkaifeng/)
3 | ###这是一个自定义相机的demo,在github上面看到的demo是用swift写的,我写了一下用oc怎么调用
4 | ### xcode版本要求 7.3
5 | ##### [原demo地址](https://github.com/AlexLittlejohn/ALCameraViewController)
6 | ###在oc中调用swift文件方法
7 | 1. 在工程中导入swift的类
8 | 2. 创建全局预编译文件 PrefixHeader.pch
9 | 3. 在预编译文件PrefixHeader.pch中 添加 #import ‘项目名-Swift.h")
10 | 4. 然后就可以在oc中使用swift的类了
11 |
12 | ###截图
13 |
14 |
15 |
16 | 
17 | 
18 | 
19 | 
20 |
--------------------------------------------------------------------------------
/SkfSwiftCammer-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // SkfSwiftCammer-Prefix.pch
3 | // SkfSwiftCammer
4 | //
5 | // Created by Kevin Sun on 16/4/13.
6 | // Copyright © 2016年 Kevin Sun. All rights reserved.
7 | //
8 |
9 | #ifndef SkfSwiftCammer_Prefix_pch
10 | #define SkfSwiftCammer_Prefix_pch
11 | #import "SkfSwiftCammer-Swift.h"
12 | #import "Masonry.h"
13 | // Include any system framework and library headers here that should be included in all compilation units.
14 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.
15 |
16 | #endif /* SkfSwiftCammer_Prefix_pch */
17 |
--------------------------------------------------------------------------------
/SkfSwiftCammer.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SkfSwiftCammer.xcodeproj/xcuserdata/Kevin.xcuserdatad/xcschemes/SkfSwiftCammer.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/SkfSwiftCammer.xcodeproj/xcuserdata/Kevin.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SkfSwiftCammer.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 0A949F771CBDEB63007F5124
16 |
17 | primary
18 |
19 |
20 | 0A949F901CBDEB63007F5124
21 |
22 | primary
23 |
24 |
25 | 0A949F9B1CBDEB63007F5124
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/ALPlaceholder.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "placeholder.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "placeholder@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "placeholder@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/ALPlaceholder.imageset/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/ALPlaceholder.imageset/placeholder.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/ALPlaceholder.imageset/placeholder@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/ALPlaceholder.imageset/placeholder@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/ALPlaceholder.imageset/placeholder@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/ALPlaceholder.imageset/placeholder@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButton.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "cameraButton.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "cameraButton@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "cameraButton@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButton.imageset/cameraButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButton.imageset/cameraButton.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButton.imageset/cameraButton@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButton.imageset/cameraButton@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButton.imageset/cameraButton@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButton.imageset/cameraButton@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButtonHighlighted.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "cameraButtonHighlighted.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "cameraButtonHighlighted@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "cameraButtonHighlighted@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/closeButton.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "closeButton.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "closeButton@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "closeButton@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/closeButton.imageset/closeButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/closeButton.imageset/closeButton.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/closeButton.imageset/closeButton@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/closeButton.imageset/closeButton@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/closeButton.imageset/closeButton@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/closeButton.imageset/closeButton@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/confirmButton.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "confirmButton.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "confirmButton@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "confirmButton@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/confirmButton.imageset/confirmButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/confirmButton.imageset/confirmButton.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/confirmButton.imageset/confirmButton@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/confirmButton.imageset/confirmButton@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/confirmButton.imageset/confirmButton@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/confirmButton.imageset/confirmButton@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashAutoIcon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "flashAutoIcon.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "flashAutoIcon@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "flashAutoIcon@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOffIcon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "flashOffIcon.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "flashOffIcon@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "flashOffIcon@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOnIcon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "flashOnIcon.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "flashOnIcon@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "flashOnIcon@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryButton.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "libraryButton.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "libraryButton@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "libraryButton@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryButton.imageset/libraryButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryButton.imageset/libraryButton.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryButton.imageset/libraryButton@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryButton.imageset/libraryButton@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryButton.imageset/libraryButton@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryButton.imageset/libraryButton@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryCancel.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "libraryCancel.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "libraryCancel@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "libraryCancel@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryConfirm.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "libraryConfirm.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "libraryConfirm@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "libraryConfirm@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/permissionsIcon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "cameraPermissionsIcon.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "cameraPermissionsIcon@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "cameraPermissionsIcon@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/retakeButton.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "retakeButton.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "retakeButton@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "retakeButton@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/retakeButton.imageset/retakeButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/retakeButton.imageset/retakeButton.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/retakeButton.imageset/retakeButton@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/retakeButton.imageset/retakeButton@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/retakeButton.imageset/retakeButton@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/retakeButton.imageset/retakeButton@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/swapButton.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "swapButton.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "swapButton@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "swapButton@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/swapButton.imageset/swapButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/swapButton.imageset/swapButton.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/swapButton.imageset/swapButton@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/swapButton.imageset/swapButton@2x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/swapButton.imageset/swapButton@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wubianxiaoxian/SkfSwiftCammer/59a6bd2016c2587ca266f27ac65b2405997daab2/SkfSwiftCammer/ALCameraViewController/ALCameraViewAssets.xcassets/swapButton.imageset/swapButton@3x.png
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/CameraView.strings:
--------------------------------------------------------------------------------
1 | /*
2 | ALCameraView.strings
3 | ALCameraViewController
4 |
5 | Created by Alex Littlejohn on 2015/06/25.
6 | Copyright (c) 2015 zero. All rights reserved.
7 | */
8 |
9 | "permissions.title" = "Camera Access Denied";
10 | "permissions.description" = "Please enable camera access in your privacy settings";
11 |
12 | "permissions.library.title" = "Photos Access Denied";
13 | "permissions.library.description" = "Please enable photo library access in your privacy settings";
14 |
15 | "permissions.settings" = "Settings";
16 |
17 | "error.cant-fetch-photo" = "Unable to fetch image";
18 | "error.cant-fetch-photo.description" = "Please check your network settings";
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Utilities/CameraGlobals.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CameraGlobals.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2016/02/16.
6 | // Copyright © 2016 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | internal let itemSpacing: CGFloat = 1
12 | internal let columns: CGFloat = 4
13 | internal let thumbnailDimension = (UIScreen.mainScreen().bounds.width - ((columns * itemSpacing) - itemSpacing))/columns
14 | internal let scale = UIScreen.mainScreen().scale
15 |
16 | public class CameraGlobals {
17 | public static let shared = CameraGlobals()
18 |
19 | var bundle = NSBundle(forClass: ALCameraViewController.self)
20 | var stringsTable = "CameraView"
21 |
22 | var photoLibraryThumbnailSize = CGSizeMake(thumbnailDimension, thumbnailDimension)
23 | }
24 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Utilities/CameraShot.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CameraShot.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2015/06/17.
6 | // Copyright (c) 2015 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import AVFoundation
11 |
12 | public typealias CameraShotCompletion = (UIImage?) -> Void
13 |
14 | public func takePhoto(stillImageOutput: AVCaptureStillImageOutput, videoOrientation: AVCaptureVideoOrientation, cropSize: CGSize, completion: CameraShotCompletion) {
15 |
16 | guard let videoConnection: AVCaptureConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) else {
17 | completion(nil)
18 | return
19 | }
20 |
21 | videoConnection.videoOrientation = videoOrientation
22 |
23 | stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: { buffer, error in
24 |
25 | guard let buffer = buffer, imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer), image = UIImage(data: imageData) else {
26 | completion(nil)
27 | return
28 | }
29 |
30 | completion(image)
31 | })
32 | }
33 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Utilities/ImageExtensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ALImageExtensions.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2015/11/06.
6 | // Copyright © 2015 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIImage {
12 | func crop(frame: CGRect, scale: CGFloat) -> UIImage {
13 |
14 | if frame.size == size && frame.origin == CGPoint.zero {
15 | return self
16 | }
17 |
18 | let drawPoint = CGPointZero
19 | UIGraphicsBeginImageContext(frame.size)
20 | let context = UIGraphicsGetCurrentContext()
21 | CGContextTranslateCTM(context, -frame.origin.x, -frame.origin.y)
22 | drawAtPoint(drawPoint)
23 | let croppedImage = UIGraphicsGetImageFromCurrentImageContext()
24 | UIGraphicsEndImageContext();
25 | return croppedImage
26 | }
27 |
28 | func fixFrontCameraOrientation() -> UIImage {
29 | var newOrient:UIImageOrientation
30 | switch imageOrientation {
31 | case .Up:
32 | newOrient = .UpMirrored
33 | case .UpMirrored:
34 | newOrient = .Up
35 | case .Down:
36 | newOrient = .DownMirrored
37 | case .DownMirrored:
38 | newOrient = .Down
39 | case .Left:
40 | newOrient = .RightMirrored
41 | case .LeftMirrored:
42 | newOrient = .Right
43 | case .Right:
44 | newOrient = .LeftMirrored
45 | case .RightMirrored:
46 | newOrient = .Left
47 | }
48 | return UIImage(CGImage: CGImage!, scale: scale, orientation: newOrient)
49 | }
50 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Utilities/ImageFetcher.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ALImageFetchingInteractor.swift
3 | // ALImagePickerViewController
4 | //
5 | // Created by Alex Littlejohn on 2015/06/09.
6 | // Copyright (c) 2015 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Photos
11 |
12 | public typealias ImageFetcherSuccess = (assets: PHFetchResult) -> ()
13 | public typealias ImageFetcherFailure = (error: NSError) -> ()
14 |
15 | extension PHFetchResult: SequenceType {
16 | public func generate() -> NSFastGenerator {
17 | return NSFastGenerator(self)
18 | }
19 | }
20 |
21 | public class ImageFetcher {
22 |
23 | private var success: ImageFetcherSuccess?
24 | private var failure: ImageFetcherFailure?
25 |
26 | private var authRequested = false
27 | private let errorDomain = "com.zero.imageFetcher"
28 |
29 | let libraryQueue = dispatch_queue_create("com.zero.ALCameraViewController.LibraryQueue", DISPATCH_QUEUE_SERIAL);
30 |
31 | public init() { }
32 |
33 | public func onSuccess(success: ImageFetcherSuccess) -> Self {
34 | self.success = success
35 | return self
36 | }
37 |
38 | public func onFailure(failure: ImageFetcherFailure) -> Self {
39 | self.failure = failure
40 | return self
41 | }
42 |
43 | public func fetch() -> Self {
44 | _ = PhotoLibraryAuthorizer { error in
45 | if error == nil {
46 | self.onAuthorized()
47 | } else {
48 | self.failure?(error: error!)
49 | }
50 | }
51 | return self
52 | }
53 |
54 | private func onAuthorized() {
55 | let options = PHFetchOptions()
56 | options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
57 | dispatch_async(libraryQueue) {
58 | let assets = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: options)
59 | dispatch_async(dispatch_get_main_queue()) {
60 | self.success?(assets: assets)
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Utilities/PhotoLibraryAuthorizer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoLibraryAuthorizer.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2016/03/26.
6 | // Copyright © 2016 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Photos
11 |
12 | public typealias PhotoLibraryAuthorizerCompletion = (error: NSError?) -> Void
13 |
14 | class PhotoLibraryAuthorizer {
15 |
16 | private let errorDomain = "com.zero.imageFetcher"
17 | private let completion: PhotoLibraryAuthorizerCompletion
18 |
19 | init(completion: PhotoLibraryAuthorizerCompletion) {
20 | self.completion = completion
21 | handleAuthorization(PHPhotoLibrary.authorizationStatus())
22 | }
23 |
24 | func onDeniedOrRestricted() {
25 | let error = errorWithKey("error.access-denied", domain: errorDomain)
26 | completion(error: error)
27 | }
28 |
29 | func handleAuthorization(status: PHAuthorizationStatus) {
30 | switch status {
31 | case .NotDetermined:
32 | PHPhotoLibrary.requestAuthorization(handleAuthorization)
33 | break
34 | case .Authorized:
35 | dispatch_async(dispatch_get_main_queue()) {
36 | self.completion(error: nil)
37 | }
38 | break
39 | case .Denied, .Restricted:
40 | dispatch_async(dispatch_get_main_queue()) {
41 | self.onDeniedOrRestricted()
42 | }
43 | break
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Utilities/SingleImageFetcher.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SingleImageFetcher.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2016/02/16.
6 | // Copyright © 2016 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Photos
11 |
12 | public typealias SingleImageFetcherSuccess = (image: UIImage) -> Void
13 | public typealias SingleImageFetcherFailure = (error: NSError) -> Void
14 |
15 | public class SingleImageFetcher {
16 | private let errorDomain = "com.zero.singleImageSaver"
17 |
18 | private var success: SingleImageFetcherSuccess?
19 | private var failure: SingleImageFetcherFailure?
20 |
21 | private var asset: PHAsset?
22 | private var targetSize = PHImageManagerMaximumSize
23 | private var cropRect: CGRect?
24 |
25 | public init() { }
26 |
27 | public func onSuccess(success: SingleImageFetcherSuccess) -> Self {
28 | self.success = success
29 | return self
30 | }
31 |
32 | public func onFailure(failure: SingleImageFetcherFailure) -> Self {
33 | self.failure = failure
34 | return self
35 | }
36 |
37 | public func setAsset(asset: PHAsset) -> Self {
38 | self.asset = asset
39 | return self
40 | }
41 |
42 | public func setTargetSize(targetSize: CGSize) -> Self {
43 | self.targetSize = targetSize
44 | return self
45 | }
46 |
47 | public func setCropRect(cropRect: CGRect) -> Self {
48 | self.cropRect = cropRect
49 | return self
50 | }
51 |
52 | public func fetch() -> Self {
53 | _ = PhotoLibraryAuthorizer { error in
54 | if error == nil {
55 | self._fetch()
56 | } else {
57 | self.failure?(error: error!)
58 | }
59 | }
60 | return self
61 | }
62 |
63 | private func _fetch() {
64 |
65 | guard let asset = asset else {
66 | let error = errorWithKey("error.cant-fetch-photo", domain: errorDomain)
67 | failure?(error: error)
68 | return
69 | }
70 |
71 | let options = PHImageRequestOptions()
72 | options.deliveryMode = .HighQualityFormat
73 | options.networkAccessAllowed = true
74 |
75 | if let cropRect = cropRect {
76 |
77 | options.normalizedCropRect = cropRect
78 | options.resizeMode = .Exact
79 |
80 | let targetWidth = floor(CGFloat(asset.pixelWidth) * cropRect.width)
81 | let targetHeight = floor(CGFloat(asset.pixelHeight) * cropRect.height)
82 | let dimension = max(min(targetHeight, targetWidth), 1024 * scale)
83 |
84 | targetSize = CGSize(width: dimension, height: dimension)
85 | }
86 |
87 | PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: targetSize, contentMode: .AspectFill, options: options) { image, _ in
88 | if let image = image {
89 | self.success?(image: image)
90 | } else {
91 | let error = errorWithKey("error.cant-fetch-photo", domain: self.errorDomain)
92 | self.failure?(error: error)
93 | }
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Utilities/SingleImageSaver.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SingleImageSavingInteractor.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2016/02/16.
6 | // Copyright © 2016 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Photos
11 |
12 | public typealias SingleImageSaverSuccess = (asset: PHAsset) -> Void
13 | public typealias SingleImageSaverFailure = (error: NSError) -> Void
14 |
15 | public class SingleImageSaver {
16 | private let errorDomain = "com.zero.singleImageSaver"
17 |
18 | private var success: SingleImageSaverSuccess?
19 | private var failure: SingleImageSaverFailure?
20 |
21 | private var image: UIImage?
22 |
23 | public init() { }
24 |
25 | public func onSuccess(success: SingleImageSaverSuccess) -> Self {
26 | self.success = success
27 | return self
28 | }
29 |
30 | public func onFailure(failure: SingleImageSaverFailure) -> Self {
31 | self.failure = failure
32 | return self
33 | }
34 |
35 | public func setImage(image: UIImage) -> Self {
36 | self.image = image
37 | return self
38 | }
39 |
40 | public func save() -> Self {
41 |
42 | _ = PhotoLibraryAuthorizer { error in
43 | if error == nil {
44 | self._save()
45 | } else {
46 | self.failure?(error: error!)
47 | }
48 | }
49 |
50 | return self
51 | }
52 |
53 | private func _save() {
54 | guard let image = image else {
55 | self.invokeFailure()
56 | return
57 | }
58 |
59 | var assetIdentifier: PHObjectPlaceholder?
60 |
61 | PHPhotoLibrary.sharedPhotoLibrary()
62 | .performChanges({
63 | let request = PHAssetChangeRequest.creationRequestForAssetFromImage(image)
64 | assetIdentifier = request.placeholderForCreatedAsset
65 | }) { finished, error in
66 |
67 | guard let assetIdentifier = assetIdentifier where finished else {
68 | self.invokeFailure()
69 | return
70 | }
71 |
72 | self.fetch(assetIdentifier)
73 | }
74 | }
75 |
76 | private func fetch(assetIdentifier: PHObjectPlaceholder) {
77 |
78 | let assets = PHAsset.fetchAssetsWithLocalIdentifiers([assetIdentifier.localIdentifier], options: nil)
79 |
80 | dispatch_async(dispatch_get_main_queue()) {
81 | guard let asset = assets.firstObject as? PHAsset else {
82 | self.invokeFailure()
83 | return
84 | }
85 |
86 | self.success?(asset: asset)
87 | }
88 | }
89 |
90 | private func invokeFailure() {
91 | let error = errorWithKey("error.cant-fetch-photo", domain: errorDomain)
92 | failure?(error: error)
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Utilities/UIButtonExtensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIButtonExtensions.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2016/03/26.
6 | // Copyright © 2016 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | typealias ButtonAction = () -> Void
12 |
13 | extension UIButton {
14 |
15 | private struct AssociatedKeys {
16 | static var ActionKey = "ActionKey"
17 | }
18 |
19 | private class ActionWrapper {
20 | let action: ButtonAction
21 | init(action: ButtonAction) {
22 | self.action = action
23 | }
24 | }
25 |
26 | var action: ButtonAction? {
27 | set(newValue) {
28 | removeTarget(self, action: #selector(UIButton.performAction), forControlEvents: UIControlEvents.TouchUpInside)
29 | var wrapper: ActionWrapper?
30 | if let newValue = newValue {
31 | wrapper = ActionWrapper(action: newValue)
32 | addTarget(self, action: #selector(UIButton.performAction), forControlEvents: UIControlEvents.TouchUpInside)
33 | }
34 |
35 | objc_setAssociatedObject(self, &AssociatedKeys.ActionKey, wrapper, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
36 | }
37 | get {
38 | guard let wrapper = objc_getAssociatedObject(self, &AssociatedKeys.ActionKey) as? ActionWrapper else {
39 | return nil
40 | }
41 |
42 | return wrapper.action
43 | }
44 | }
45 |
46 | func performAction() {
47 | if let a = action {
48 | a()
49 | }
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Utilities/Utilities.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ALUtilities.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2015/06/25.
6 | // Copyright (c) 2015 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | internal func radians(degrees: Double) -> Double {
12 | return degrees / 180 * M_PI
13 | }
14 |
15 | internal func localizedString(key: String) -> String {
16 | return NSLocalizedString(key, tableName: CameraGlobals.shared.stringsTable, bundle: CameraGlobals.shared.bundle, comment: key)
17 | }
18 |
19 | internal func currentRotation() -> Double {
20 | var rotation: Double = 0
21 |
22 | if UIDevice.currentDevice().orientation == .LandscapeLeft {
23 | rotation = 90
24 | } else if UIDevice.currentDevice().orientation == .LandscapeRight {
25 | rotation = 270
26 | } else if UIDevice.currentDevice().orientation == .PortraitUpsideDown {
27 | rotation = 180
28 | }
29 |
30 | return rotation
31 | }
32 |
33 | internal func largestPhotoSize() -> CGSize {
34 | let scale = UIScreen.mainScreen().scale
35 | let screenSize = UIScreen.mainScreen().bounds.size
36 | let size = CGSize(width: screenSize.width * scale, height: screenSize.height * scale)
37 | return size
38 | }
39 |
40 | internal func errorWithKey(key: String, domain: String) -> NSError {
41 | let errorString = localizedString(key)
42 | let errorInfo = [NSLocalizedDescriptionKey: errorString]
43 | let error = NSError(domain: domain, code: 0, userInfo: errorInfo)
44 | return error
45 | }
46 |
47 | internal func normalizedRect(rect: CGRect, orientation: UIImageOrientation) -> CGRect {
48 | let normalizedX = rect.origin.x
49 | let normalizedY = rect.origin.y
50 |
51 | let normalizedWidth = rect.width
52 | let normalizedHeight = rect.height
53 |
54 | var normalizedRect: CGRect
55 |
56 | switch orientation {
57 | case .Up, .UpMirrored:
58 | normalizedRect = CGRect(x: normalizedX, y: normalizedY, width: normalizedWidth, height: normalizedHeight)
59 | case .Down, .DownMirrored:
60 | normalizedRect = CGRect(x: 1-normalizedX-normalizedWidth, y: 1-normalizedY-normalizedHeight, width: normalizedWidth, height: normalizedHeight)
61 | case .Left, .LeftMirrored:
62 | normalizedRect = CGRect(x: 1-normalizedY-normalizedHeight, y: normalizedX, width: normalizedHeight, height: normalizedWidth)
63 | case .Right, .RightMirrored:
64 | normalizedRect = CGRect(x: normalizedY, y: 1-normalizedX-normalizedWidth, width: normalizedHeight, height: normalizedWidth)
65 | }
66 |
67 | return normalizedRect
68 |
69 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Utilities/VolumeControl.swift:
--------------------------------------------------------------------------------
1 | //
2 | // VolumeControl.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2016/03/26.
6 | // Copyright © 2016 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import MediaPlayer
11 |
12 | typealias VolumeChangeAction = (volume: Float) -> Void
13 |
14 | public class VolumeControl {
15 |
16 | let changeKey = "AVSystemController_SystemVolumeDidChangeNotification"
17 |
18 | lazy var volumeView: MPVolumeView = {
19 | let view = MPVolumeView()
20 | view.frame = CGRect(x: 0, y: 0, width: 1, height: 1)
21 | view.alpha = 0.01
22 | return view
23 | }()
24 |
25 | var onVolumeChange: VolumeChangeAction?
26 |
27 | init(view: UIView, onVolumeChange: VolumeChangeAction?) {
28 |
29 | self.onVolumeChange = onVolumeChange
30 | configureInView(view)
31 |
32 | try! AVAudioSession.sharedInstance().setActive(true)
33 |
34 | NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(volumeChanged), name: changeKey, object: nil)
35 | }
36 |
37 | deinit {
38 | try! AVAudioSession.sharedInstance().setActive(false)
39 | NSNotificationCenter.defaultCenter().removeObserver(self)
40 | onVolumeChange = nil
41 | volumeView.removeFromSuperview()
42 | }
43 |
44 | func configureInView(view: UIView) {
45 | view.addSubview(volumeView)
46 | view.sendSubviewToBack(volumeView)
47 | }
48 |
49 | @objc func volumeChanged() {
50 | guard let slider = volumeView.subviews.filter({ $0 is UISlider }).first as? UISlider else { return }
51 | let volume = AVAudioSession.sharedInstance().outputVolume
52 | slider.setValue(volume, animated: false)
53 | onVolumeChange?(volume: volume)
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ViewController/ALCameraViewController-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 | #import "KevinViewController.h"
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ViewController/ConfirmViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ALConfirmViewController.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2015/06/30.
6 | // Copyright (c) 2015 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Photos
11 |
12 | internal class ConfirmViewController: UIViewController, UIScrollViewDelegate {
13 |
14 | let imageView = UIImageView()
15 | @IBOutlet weak var scrollView: UIScrollView!
16 | @IBOutlet weak var cropOverlay: CropOverlay!
17 | @IBOutlet weak var cancelButton: UIButton!
18 | @IBOutlet weak var confirmButton: UIButton!
19 | @IBOutlet weak var centeringView: UIView!
20 |
21 | var allowsCropping: Bool = false
22 | var verticalPadding: CGFloat = 30
23 | var horizontalPadding: CGFloat = 30
24 |
25 | var onComplete: CameraViewCompletion?
26 |
27 | var asset: PHAsset!
28 |
29 | internal init(asset: PHAsset, allowsCropping: Bool) {
30 | self.allowsCropping = allowsCropping
31 | self.asset = asset
32 | super.init(nibName: "ConfirmViewController", bundle: CameraGlobals.shared.bundle)
33 | commonInit()
34 | NSLog("ssss")
35 | }
36 |
37 | internal required init?(coder aDecoder: NSCoder) {
38 | super.init(coder: aDecoder)
39 | }
40 |
41 | func commonInit() {
42 | if UIScreen.mainScreen().bounds.width <= 320 {
43 | horizontalPadding = 15
44 | }
45 | }
46 |
47 | internal override func prefersStatusBarHidden() -> Bool {
48 | return true
49 | }
50 |
51 | internal override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
52 | return UIStatusBarAnimation.Slide
53 | }
54 |
55 | internal override func viewDidLoad() {
56 | super.viewDidLoad()
57 |
58 | view.backgroundColor = UIColor.blackColor()
59 |
60 | scrollView.addSubview(imageView)
61 | scrollView.delegate = self
62 | scrollView.maximumZoomScale = 1
63 |
64 | cropOverlay.hidden = true
65 |
66 | guard let asset = asset else {
67 | return
68 | }
69 |
70 | let spinner = showSpinner()
71 |
72 | disable()
73 |
74 | SingleImageFetcher()
75 | .setAsset(asset)
76 | .setTargetSize(largestPhotoSize())
77 | .onSuccess { image in
78 | self.configureWithImage(image)
79 | self.hideSpinner(spinner)
80 | self.enable()
81 | }
82 | .onFailure { error in
83 | self.hideSpinner(spinner)
84 | }
85 | .fetch()
86 | }
87 |
88 | override func viewWillLayoutSubviews() {
89 | super.viewWillLayoutSubviews()
90 | let scale = calculateMinimumScale(view.frame.size)
91 | let frame = allowsCropping ? cropOverlay.frame : view.bounds
92 |
93 | scrollView.contentInset = calculateScrollViewInsets(frame)
94 | scrollView.minimumZoomScale = scale
95 | scrollView.zoomScale = scale
96 | centerScrollViewContents()
97 | centerImageViewOnRotate()
98 | }
99 |
100 | override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
101 | super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
102 |
103 | let scale = calculateMinimumScale(size)
104 | var frame = view.bounds
105 |
106 | if allowsCropping {
107 | frame = cropOverlay.frame
108 | let centeringFrame = centeringView.frame
109 | var origin: CGPoint
110 |
111 | if size.width > size.height { // landscape
112 | let offset = (size.width - centeringFrame.height)
113 | let expectedX = (centeringFrame.height/2 - frame.height/2) + offset
114 | origin = CGPoint(x: expectedX, y: frame.origin.x)
115 | } else {
116 | let expectedY = (centeringFrame.width/2 - frame.width/2)
117 | origin = CGPoint(x: frame.origin.y, y: expectedY)
118 | }
119 |
120 | frame.origin = origin
121 | } else {
122 | frame.size = size
123 | }
124 |
125 | coordinator.animateAlongsideTransition({ context in
126 | self.scrollView.contentInset = self.calculateScrollViewInsets(frame)
127 | self.scrollView.minimumZoomScale = scale
128 | self.scrollView.zoomScale = scale
129 | self.centerScrollViewContents()
130 | self.centerImageViewOnRotate()
131 | }, completion: nil)
132 | }
133 |
134 | private func configureWithImage(image: UIImage) {
135 | if allowsCropping {
136 | cropOverlay.hidden = false
137 | } else {
138 | cropOverlay.hidden = true
139 | }
140 |
141 | buttonActions()
142 |
143 | imageView.image = image
144 | imageView.sizeToFit()
145 | view.setNeedsLayout()
146 | }
147 |
148 | private func calculateMinimumScale(size: CGSize) -> CGFloat {
149 | var _size = size
150 |
151 | if allowsCropping {
152 | _size = cropOverlay.frame.size
153 | }
154 |
155 | guard let image = imageView.image else {
156 | return 1
157 | }
158 |
159 | let scaleWidth = _size.width / image.size.width
160 | let scaleHeight = _size.height / image.size.height
161 |
162 | var scale: CGFloat
163 |
164 | if allowsCropping {
165 | scale = max(scaleWidth, scaleHeight)
166 | } else {
167 | scale = min(scaleWidth, scaleHeight)
168 | }
169 |
170 | return scale
171 | }
172 |
173 | private func calculateScrollViewInsets(frame: CGRect) -> UIEdgeInsets {
174 | let bottom = view.frame.height - (frame.origin.y + frame.height)
175 | let right = view.frame.width - (frame.origin.x + frame.width)
176 | let insets = UIEdgeInsets(top: frame.origin.y, left: frame.origin.x, bottom: bottom, right: right)
177 | return insets
178 | }
179 |
180 | private func centerImageViewOnRotate() {
181 | if allowsCropping {
182 | let size = allowsCropping ? cropOverlay.frame.size : scrollView.frame.size
183 | let scrollInsets = scrollView.contentInset
184 | let imageSize = imageView.frame.size
185 | var contentOffset = CGPoint(x: -scrollInsets.left, y: -scrollInsets.top)
186 | contentOffset.x -= (size.width - imageSize.width) / 2
187 | contentOffset.y -= (size.height - imageSize.height) / 2
188 | scrollView.contentOffset = contentOffset
189 | }
190 | }
191 |
192 | private func centerScrollViewContents() {
193 | let size = allowsCropping ? cropOverlay.frame.size : scrollView.frame.size
194 | let imageSize = imageView.frame.size
195 | var imageOrigin = CGPoint.zero
196 |
197 | if imageSize.width < size.width {
198 | imageOrigin.x = (size.width - imageSize.width) / 2
199 | }
200 |
201 | if imageSize.height < size.height {
202 | imageOrigin.y = (size.height - imageSize.height) / 2
203 | }
204 |
205 | imageView.frame.origin = imageOrigin
206 | }
207 |
208 | private func buttonActions() {
209 | confirmButton.addTarget(self, action: #selector(ConfirmViewController.confirmPhoto), forControlEvents: UIControlEvents.TouchUpInside)
210 | cancelButton.addTarget(self, action: #selector(ConfirmViewController.cancel), forControlEvents: UIControlEvents.TouchUpInside)
211 | }
212 |
213 | internal func cancel() {
214 | onComplete?(nil, nil)
215 | }
216 |
217 | internal func confirmPhoto() {
218 |
219 | disable()
220 |
221 | imageView.hidden = true
222 |
223 | let spinner = showSpinner()
224 |
225 | let fetcher = SingleImageFetcher()
226 | .onSuccess { image in
227 | self.onComplete?(image, self.asset)
228 | self.hideSpinner(spinner)
229 | self.enable()
230 | }
231 | .onFailure { error in
232 | self.hideSpinner(spinner)
233 | self.showNoImageScreen(error)
234 | }
235 | .setAsset(asset)
236 |
237 | if allowsCropping {
238 |
239 | var cropRect = cropOverlay.frame
240 | cropRect.origin.x += scrollView.contentOffset.x
241 | cropRect.origin.y += scrollView.contentOffset.y
242 |
243 | let normalizedX = cropRect.origin.x / imageView.frame.width
244 | let normalizedY = cropRect.origin.y / imageView.frame.height
245 |
246 | let normalizedWidth = cropRect.width / imageView.frame.width
247 | let normalizedHeight = cropRect.height / imageView.frame.height
248 |
249 | let rect = normalizedRect(CGRect(x: normalizedX, y: normalizedY, width: normalizedWidth, height: normalizedHeight), orientation: imageView.image!.imageOrientation)
250 |
251 | fetcher.setCropRect(rect)
252 | }
253 |
254 | fetcher.fetch()
255 | }
256 |
257 | internal func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
258 | return imageView
259 | }
260 |
261 | internal func scrollViewDidZoom(scrollView: UIScrollView) {
262 | centerScrollViewContents()
263 | }
264 |
265 | func showSpinner() -> UIActivityIndicatorView {
266 | let spinner = UIActivityIndicatorView()
267 | spinner.activityIndicatorViewStyle = .White
268 | spinner.center = view.center
269 | spinner.startAnimating()
270 |
271 | view.addSubview(spinner)
272 | view.bringSubviewToFront(spinner)
273 |
274 | return spinner
275 | }
276 |
277 | func hideSpinner(spinner: UIActivityIndicatorView) {
278 | spinner.stopAnimating()
279 | spinner.removeFromSuperview()
280 | }
281 |
282 | func disable() {
283 | confirmButton.enabled = false
284 | }
285 |
286 | func enable() {
287 | confirmButton.enabled = true
288 | }
289 |
290 | func showNoImageScreen(error: NSError) {
291 | let permissionsView = PermissionsView(frame: view.bounds)
292 |
293 | let desc = localizedString("error.cant-fetch-photo.description")
294 |
295 | permissionsView.configureInView(view, title: error.localizedDescription, descriptiom: desc, completion: cancel)
296 | }
297 |
298 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/ViewController/PhotoLibraryViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ALImagePickerViewController.swift
3 | // ALImagePickerViewController
4 | //
5 | // Created by Alex Littlejohn on 2015/06/09.
6 | // Copyright (c) 2015 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Photos
11 |
12 | internal let ImageCellIdentifier = "ImageCell"
13 |
14 | internal let defaultItemSpacing: CGFloat = 1
15 |
16 | public typealias PhotoLibraryViewSelectionComplete = (asset: PHAsset?) -> Void
17 |
18 | public class PhotoLibraryViewController: UIViewController {
19 |
20 | public var onSelectionComplete: PhotoLibraryViewSelectionComplete?
21 |
22 | private lazy var collectionView: UICollectionView = {
23 | let layout = UICollectionViewFlowLayout()
24 |
25 | layout.itemSize = CameraGlobals.shared.photoLibraryThumbnailSize
26 | layout.minimumInteritemSpacing = defaultItemSpacing
27 | layout.minimumLineSpacing = defaultItemSpacing
28 | layout.sectionInset = UIEdgeInsetsZero
29 | NSLog("ss");
30 |
31 | return UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
32 | }()
33 |
34 | private var assets: PHFetchResult!
35 |
36 | public override func viewDidLoad() {
37 | super.viewDidLoad()
38 |
39 | setNeedsStatusBarAppearanceUpdate()
40 | view.backgroundColor = UIColor(white: 0.2, alpha: 1)
41 | view.addSubview(collectionView)
42 |
43 | collectionView.backgroundColor = UIColor.clearColor()
44 |
45 | let buttonImage = UIImage(named: "libraryCancel", inBundle: CameraGlobals.shared.bundle, compatibleWithTraitCollection: nil)?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
46 |
47 | navigationItem.leftBarButtonItem = UIBarButtonItem(image: buttonImage, style: UIBarButtonItemStyle.Plain, target: self, action: #selector(dismiss))
48 |
49 | ImageFetcher()
50 | .onFailure(onFailure)
51 | .onSuccess(onSuccess)
52 | .fetch()
53 | }
54 |
55 | public override func preferredStatusBarStyle() -> UIStatusBarStyle {
56 | return UIStatusBarStyle.LightContent
57 | }
58 |
59 | public override func viewWillLayoutSubviews() {
60 | super.viewWillLayoutSubviews()
61 | collectionView.frame = view.frame
62 | }
63 |
64 | public func present(inViewController: UIViewController, animated: Bool) {
65 |
66 | let navigationController = UINavigationController(rootViewController: self)
67 |
68 | navigationController.navigationBar.barTintColor = UIColor.blackColor()
69 | navigationController.navigationBar.barStyle = UIBarStyle.Black
70 |
71 | inViewController.presentViewController(navigationController, animated: animated, completion: nil)
72 | }
73 |
74 | public func dismiss() {
75 | onSelectionComplete?(asset: nil)
76 | }
77 |
78 | private func onSuccess(photos: PHFetchResult) {
79 | assets = photos
80 | configureCollectionView()
81 | }
82 |
83 | private func onFailure(error: NSError) {
84 | let permissionsView = PermissionsView(frame: view.bounds)
85 | permissionsView.titleLabel.text = localizedString("permissions.library.title")
86 | permissionsView.descriptionLabel.text = localizedString("permissions.library.description")
87 |
88 | view.addSubview(permissionsView)
89 | }
90 |
91 | private func configureCollectionView() {
92 | collectionView.registerClass(ImageCell.self, forCellWithReuseIdentifier: ImageCellIdentifier)
93 | collectionView.delegate = self
94 | collectionView.dataSource = self
95 | }
96 |
97 | private func itemAtIndexPath(indexPath: NSIndexPath) -> PHAsset {
98 | return assets[indexPath.row] as! PHAsset
99 | }
100 | }
101 |
102 | // MARK: - UICollectionViewDataSource -
103 | extension PhotoLibraryViewController : UICollectionViewDataSource {
104 | public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
105 | return assets.count
106 | }
107 |
108 | public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
109 |
110 | let model = itemAtIndexPath(indexPath)
111 | let cell = collectionView.dequeueReusableCellWithReuseIdentifier(ImageCellIdentifier, forIndexPath: indexPath) as! ImageCell
112 |
113 | cell.configureWithModel(model)
114 |
115 | return cell
116 | }
117 | }
118 |
119 | // MARK: - UICollectionViewDelegate -
120 | extension PhotoLibraryViewController : UICollectionViewDelegateFlowLayout {
121 | public func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
122 | let asset = itemAtIndexPath(indexPath)
123 | onSelectionComplete?(asset: asset)
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Views/CameraView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CameraView.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2015/06/17.
6 | // Copyright (c) 2015 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import AVFoundation
11 |
12 | public class CameraView: UIView {
13 |
14 | var session: AVCaptureSession!
15 | var input: AVCaptureDeviceInput!
16 | var device: AVCaptureDevice!
17 | var imageOutput: AVCaptureStillImageOutput!
18 | var preview: AVCaptureVideoPreviewLayer!
19 |
20 | let cameraQueue = dispatch_queue_create("com.zero.ALCameraViewController.Queue", DISPATCH_QUEUE_SERIAL);
21 |
22 | let focusView = CropOverlay(frame: CGRect(x: 0, y: 0, width: 80, height: 80))
23 |
24 | public var currentPosition = AVCaptureDevicePosition.Back
25 |
26 | public func startSession() {
27 | dispatch_async(cameraQueue) {
28 | self.createSession()
29 | self.session?.startRunning()
30 | }
31 | }
32 |
33 | public func stopSession() {
34 | dispatch_async(cameraQueue) {
35 | self.session?.stopRunning()
36 | self.preview?.removeFromSuperlayer()
37 |
38 | self.session = nil
39 | self.input = nil
40 | self.imageOutput = nil
41 | self.preview = nil
42 | self.device = nil
43 | }
44 | }
45 |
46 | public override func layoutSubviews() {
47 | super.layoutSubviews()
48 | preview?.frame = bounds
49 | }
50 |
51 | public func configureFocus() {
52 |
53 | if let gestureRecognizers = gestureRecognizers {
54 | for gesture in gestureRecognizers {
55 | removeGestureRecognizer(gesture)
56 | }
57 | }
58 |
59 | let tapGesture = UITapGestureRecognizer(target: self, action: #selector(CameraView.focus(_:)))
60 | addGestureRecognizer(tapGesture)
61 | userInteractionEnabled = true
62 | addSubview(focusView)
63 |
64 | focusView.hidden = true
65 |
66 | let lines = focusView.horizontalLines + focusView.verticalLines + focusView.outerLines
67 |
68 | lines.forEach { line in
69 | line.alpha = 0
70 | }
71 | }
72 |
73 | internal func focus(gesture: UITapGestureRecognizer) {
74 | let point = gesture.locationInView(self)
75 |
76 | guard focusCamera(point) else {
77 | return
78 | }
79 |
80 | focusView.hidden = false
81 | focusView.center = point
82 | focusView.alpha = 0
83 | focusView.transform = CGAffineTransformMakeScale(1.2, 1.2)
84 |
85 | bringSubviewToFront(focusView)
86 |
87 | UIView.animateKeyframesWithDuration(1.5, delay: 0, options: UIViewKeyframeAnimationOptions(), animations: {
88 |
89 | UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0.15, animations: { () -> Void in
90 | self.focusView.alpha = 1
91 | self.focusView.transform = CGAffineTransformIdentity
92 | })
93 |
94 | UIView.addKeyframeWithRelativeStartTime(0.80, relativeDuration: 0.20, animations: { () -> Void in
95 | self.focusView.alpha = 0
96 | self.focusView.transform = CGAffineTransformMakeScale(0.8, 0.8)
97 | })
98 |
99 |
100 | }, completion: { finished in
101 | if finished {
102 | self.focusView.hidden = true
103 | }
104 | })
105 | }
106 |
107 | private func createSession() {
108 | session = AVCaptureSession()
109 | session.sessionPreset = AVCaptureSessionPresetHigh
110 | dispatch_async(dispatch_get_main_queue()) {
111 | self.createPreview()
112 | }
113 | }
114 |
115 | private func createPreview() {
116 | device = cameraWithPosition(currentPosition)
117 | if device.hasFlash {
118 | do {
119 | try device.lockForConfiguration()
120 | device.flashMode = .Auto
121 | device.unlockForConfiguration()
122 | } catch _ {}
123 | }
124 |
125 | let outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
126 |
127 | do {
128 | input = try AVCaptureDeviceInput(device: device)
129 | } catch let error as NSError {
130 | input = nil
131 | print("Error: \(error.localizedDescription)")
132 | return
133 | }
134 |
135 | if session.canAddInput(input) {
136 | session.addInput(input)
137 | }
138 |
139 | imageOutput = AVCaptureStillImageOutput()
140 | imageOutput.outputSettings = outputSettings
141 |
142 | session.addOutput(imageOutput)
143 |
144 | preview = AVCaptureVideoPreviewLayer(session: session)
145 | preview.videoGravity = AVLayerVideoGravityResizeAspectFill
146 | preview.frame = bounds
147 |
148 | layer.addSublayer(preview)
149 | }
150 |
151 | private func cameraWithPosition(position: AVCaptureDevicePosition) -> AVCaptureDevice? {
152 | guard let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as? [AVCaptureDevice] else {
153 | return nil
154 | }
155 | return devices.filter { $0.position == position }.first
156 | }
157 |
158 | public func capturePhoto(completion: CameraShotCompletion) {
159 | dispatch_async(cameraQueue) {
160 | let orientation = AVCaptureVideoOrientation(rawValue: UIDevice.currentDevice().orientation.rawValue)!
161 | takePhoto(self.imageOutput, videoOrientation: orientation, cropSize: self.frame.size) { image in
162 | dispatch_async(dispatch_get_main_queue()) {
163 | completion(image)
164 | }
165 | }
166 | }
167 | }
168 |
169 | public func focusCamera(toPoint: CGPoint) -> Bool {
170 |
171 | guard let device = device where device.isFocusModeSupported(.ContinuousAutoFocus) else {
172 | return false
173 | }
174 |
175 | do { try device.lockForConfiguration() } catch {
176 | return false
177 | }
178 |
179 | // focus points are in the range of 0...1, not screen pixels
180 | let focusPoint = CGPoint(x: toPoint.x / frame.width, y: toPoint.y / frame.height)
181 |
182 | device.focusMode = AVCaptureFocusMode.ContinuousAutoFocus
183 | device.exposurePointOfInterest = focusPoint
184 | device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure
185 | device.unlockForConfiguration()
186 |
187 | return true
188 | }
189 |
190 | public func swapCameraInput() {
191 |
192 | guard let session = session, input = input else {
193 | return
194 | }
195 |
196 | session.beginConfiguration()
197 | session.removeInput(input)
198 |
199 | if input.device.position == AVCaptureDevicePosition.Back {
200 | currentPosition = AVCaptureDevicePosition.Front
201 | device = cameraWithPosition(currentPosition)
202 | } else {
203 | currentPosition = AVCaptureDevicePosition.Back
204 | device = cameraWithPosition(currentPosition)
205 | }
206 |
207 | guard let i = try? AVCaptureDeviceInput(device: device) else {
208 | return
209 | }
210 |
211 | self.input = i
212 |
213 | session.addInput(i)
214 | session.commitConfiguration()
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Views/CropOverlay.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CropOverlay.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2015/06/30.
6 | // Copyright (c) 2015 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | internal class CropOverlay: UIView {
12 |
13 | var outerLines = [UIView]()
14 | var horizontalLines = [UIView]()
15 | var verticalLines = [UIView]()
16 |
17 | var topLeftCornerLines = [UIView]()
18 | var topRightCornerLines = [UIView]()
19 | var bottomLeftCornerLines = [UIView]()
20 | var bottomRightCornerLines = [UIView]()
21 |
22 | let cornerDepth: CGFloat = 3
23 | let cornerWidth: CGFloat = 20
24 | let lineWidth: CGFloat = 1
25 |
26 | internal init() {
27 | super.init(frame: CGRectZero)
28 | createLines()
29 | }
30 |
31 | internal override init(frame: CGRect) {
32 | super.init(frame: frame)
33 | createLines()
34 | }
35 |
36 | internal required init?(coder aDecoder: NSCoder) {
37 | super.init(coder: aDecoder)
38 | createLines()
39 | }
40 |
41 | override func layoutSubviews() {
42 |
43 | let size = bounds.size
44 |
45 | for i in 0.. UIView {
132 | let line = UIView()
133 | line.backgroundColor = UIColor.whiteColor()
134 | addSubview(line)
135 | return line
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Views/ImageCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImageCell.swift
3 | // ALImagePickerViewController
4 | //
5 | // Created by Alex Littlejohn on 2015/06/09.
6 | // Copyright (c) 2015 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Photos
11 |
12 | class ImageCell: UICollectionViewCell {
13 |
14 | let imageView = UIImageView()
15 |
16 | override init(frame: CGRect) {
17 | super.init(frame: frame)
18 | commonInit()
19 | }
20 |
21 | required init?(coder aDecoder: NSCoder) {
22 | super.init(coder: aDecoder)
23 | commonInit()
24 | }
25 |
26 | func commonInit() {
27 | contentView.addSubview(imageView)
28 |
29 | imageView.contentMode = .ScaleAspectFill
30 | imageView.layer.masksToBounds = true
31 | }
32 |
33 | override func layoutSubviews() {
34 | super.layoutSubviews()
35 | imageView.frame = bounds
36 | }
37 |
38 | override func prepareForReuse() {
39 | super.prepareForReuse()
40 | imageView.image = UIImage(named: "ALPlaceholder", inBundle: CameraGlobals.shared.bundle, compatibleWithTraitCollection: nil)
41 | }
42 |
43 | func configureWithModel(model: PHAsset) {
44 |
45 | imageView.image = UIImage(named: "ALPlaceholder", inBundle: CameraGlobals.shared.bundle, compatibleWithTraitCollection: nil)
46 |
47 | if tag != 0 {
48 | PHImageManager.defaultManager().cancelImageRequest(PHImageRequestID(tag))
49 | }
50 |
51 | var thumbnailSize = CameraGlobals.shared.photoLibraryThumbnailSize
52 | thumbnailSize.width *= scale
53 | thumbnailSize.height *= scale
54 |
55 | tag = Int(PHImageManager.defaultManager().requestImageForAsset(model, targetSize: thumbnailSize, contentMode: .AspectFill, options: nil) { image, info in
56 | self.imageView.image = image
57 | })
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ALCameraViewController/Views/PermissionsView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PermissionsView.swift
3 | // ALCameraViewController
4 | //
5 | // Created by Alex Littlejohn on 2015/06/24.
6 | // Copyright (c) 2015 zero. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | internal class PermissionsView: UIView {
12 |
13 | let iconView = UIImageView()
14 | let titleLabel = UILabel()
15 | let descriptionLabel = UILabel()
16 | let settingsButton = UIButton()
17 |
18 | let horizontalPadding: CGFloat = 50
19 | let verticalPadding: CGFloat = 50
20 | let verticalSpacing: CGFloat = 10
21 |
22 | required init?(coder aDecoder: NSCoder) {
23 | super.init(coder: aDecoder)
24 | commonInit()
25 | }
26 |
27 | override init(frame: CGRect) {
28 | super.init(frame: frame)
29 | commonInit()
30 | }
31 |
32 | func configureInView(view: UIView, title: String, descriptiom: String, completion: () -> Void) {
33 | let closeButton = UIButton(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
34 |
35 | view.addSubview(self)
36 | addSubview(closeButton)
37 |
38 | titleLabel.text = title
39 | descriptionLabel.text = descriptiom
40 |
41 | closeButton.action = completion
42 | closeButton.setImage(UIImage(named: "retakeButton", inBundle: CameraGlobals.shared.bundle, compatibleWithTraitCollection: nil), forState: UIControlState.Normal)
43 | closeButton.sizeToFit()
44 |
45 | let size = view.frame.size
46 | let closeSize = closeButton.frame.size
47 | let closeX = horizontalPadding
48 | let closeY = size.height - (closeSize.height + verticalPadding)
49 |
50 | closeButton.frame.origin = CGPoint(x: closeX, y: closeY)
51 | }
52 |
53 | func commonInit() {
54 |
55 | backgroundColor = UIColor(white: 0.2, alpha: 1)
56 |
57 | titleLabel.textColor = UIColor.whiteColor()
58 | titleLabel.numberOfLines = 0
59 | titleLabel.textAlignment = NSTextAlignment.Center
60 | titleLabel.font = UIFont(name: "AppleSDGothicNeo-Light", size: 22)
61 | titleLabel.text = localizedString("permissions.title")
62 |
63 | descriptionLabel.textColor = UIColor.lightGrayColor()
64 | descriptionLabel.numberOfLines = 0
65 | descriptionLabel.textAlignment = NSTextAlignment.Center
66 | descriptionLabel.font = UIFont(name: "AppleSDGothicNeo-Regular", size: 16)
67 | descriptionLabel.text = localizedString("permissions.description")
68 |
69 | let icon = UIImage(named: "permissionsIcon", inBundle: CameraGlobals.shared.bundle, compatibleWithTraitCollection: nil)!
70 | iconView.image = icon
71 |
72 | settingsButton.contentEdgeInsets = UIEdgeInsetsMake(6, 12, 6, 12)
73 | settingsButton.setTitle(localizedString("permissions.settings"), forState: UIControlState.Normal)
74 | settingsButton.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
75 | settingsButton.layer.cornerRadius = 4
76 | settingsButton.titleLabel?.font = UIFont(name: "AppleSDGothicNeo-Regular", size: 14)
77 | settingsButton.backgroundColor = UIColor(red: 52.0/255.0, green: 183.0/255.0, blue: 250.0/255.0, alpha: 1)
78 | settingsButton.addTarget(self, action: #selector(PermissionsView.openSettings), forControlEvents: UIControlEvents.TouchUpInside)
79 |
80 | addSubview(iconView)
81 | addSubview(titleLabel)
82 | addSubview(descriptionLabel)
83 | addSubview(settingsButton)
84 | }
85 |
86 | func openSettings() {
87 | if let appSettings = NSURL(string: UIApplicationOpenSettingsURLString) {
88 | UIApplication.sharedApplication().openURL(appSettings)
89 | }
90 | }
91 |
92 | override func layoutSubviews() {
93 | super.layoutSubviews()
94 |
95 | let maxLabelWidth = frame.width - horizontalPadding * 2
96 |
97 | let iconSize = iconView.image!.size
98 | let constrainedTextSize = CGSize(width: maxLabelWidth, height: CGFloat.max)
99 | let titleSize = titleLabel.sizeThatFits(constrainedTextSize)
100 | let descriptionSize = descriptionLabel.sizeThatFits(constrainedTextSize)
101 | let settingsSize = settingsButton.sizeThatFits(constrainedTextSize)
102 |
103 | let iconX = frame.width/2 - iconSize.width/2
104 | let iconY: CGFloat = frame.height/2 - (iconSize.height + verticalSpacing + verticalSpacing + titleSize.height + verticalSpacing + descriptionSize.height)/2;
105 |
106 | iconView.frame = CGRect(x: iconX, y: iconY, width: iconSize.width, height: iconSize.height)
107 |
108 | let titleX = frame.width/2 - titleSize.width/2
109 | let titleY = iconY + iconSize.height + verticalSpacing + verticalSpacing
110 |
111 | titleLabel.frame = CGRect(x: titleX, y: titleY, width: titleSize.width, height: titleSize.height)
112 |
113 | let descriptionX = frame.width/2 - descriptionSize.width/2
114 | let descriptionY = titleY + titleSize.height + verticalSpacing
115 |
116 | descriptionLabel.frame = CGRect(x: descriptionX, y: descriptionY, width: descriptionSize.width, height: descriptionSize.height)
117 |
118 | let settingsX = frame.width/2 - settingsSize.width/2
119 | let settingsY = descriptionY + descriptionSize.height + verticalSpacing
120 |
121 | settingsButton.frame = CGRect(x: settingsX, y: settingsY, width: settingsSize.width, height: settingsSize.height)
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // SkfSwiftCammer
4 | //
5 | // Created by Kevin Sun on 16/4/13.
6 | // Copyright © 2016年 Kevin Sun. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // SkfSwiftCammer
4 | //
5 | // Created by Kevin Sun on 16/4/13.
6 | // Copyright © 2016年 Kevin Sun. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/SkfSwiftCammer/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 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/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 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
50 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/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 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.cloudling.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASCompositeConstraint.h:
--------------------------------------------------------------------------------
1 | //
2 | // MASCompositeConstraint.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 21/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import "MASConstraint.h"
10 | #import "MASUtilities.h"
11 |
12 | /**
13 | * A group of MASConstraint objects
14 | */
15 | @interface MASCompositeConstraint : MASConstraint
16 |
17 | /**
18 | * Creates a composite with a predefined array of children
19 | *
20 | * @param children child MASConstraints
21 | *
22 | * @return a composite constraint
23 | */
24 | - (id)initWithChildren:(NSArray *)children;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASCompositeConstraint.m:
--------------------------------------------------------------------------------
1 | //
2 | // MASCompositeConstraint.m
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 21/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import "MASCompositeConstraint.h"
10 | #import "MASConstraint+Private.h"
11 |
12 | @interface MASCompositeConstraint ()
13 |
14 | @property (nonatomic, strong) id mas_key;
15 | @property (nonatomic, strong) NSMutableArray *childConstraints;
16 |
17 | @end
18 |
19 | @implementation MASCompositeConstraint
20 |
21 | - (id)initWithChildren:(NSArray *)children {
22 | self = [super init];
23 | if (!self) return nil;
24 |
25 | _childConstraints = [children mutableCopy];
26 | for (MASConstraint *constraint in _childConstraints) {
27 | constraint.delegate = self;
28 | }
29 |
30 | return self;
31 | }
32 |
33 | #pragma mark - MASConstraintDelegate
34 |
35 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint {
36 | NSUInteger index = [self.childConstraints indexOfObject:constraint];
37 | NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);
38 | [self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint];
39 | }
40 |
41 | - (MASConstraint *)constraint:(MASConstraint __unused *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
42 | id strongDelegate = self.delegate;
43 | MASConstraint *newConstraint = [strongDelegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
44 | newConstraint.delegate = self;
45 | [self.childConstraints addObject:newConstraint];
46 | return newConstraint;
47 | }
48 |
49 | #pragma mark - NSLayoutConstraint multiplier proxies
50 |
51 | - (MASConstraint * (^)(CGFloat))multipliedBy {
52 | return ^id(CGFloat multiplier) {
53 | for (MASConstraint *constraint in self.childConstraints) {
54 | constraint.multipliedBy(multiplier);
55 | }
56 | return self;
57 | };
58 | }
59 |
60 | - (MASConstraint * (^)(CGFloat))dividedBy {
61 | return ^id(CGFloat divider) {
62 | for (MASConstraint *constraint in self.childConstraints) {
63 | constraint.dividedBy(divider);
64 | }
65 | return self;
66 | };
67 | }
68 |
69 | #pragma mark - MASLayoutPriority proxy
70 |
71 | - (MASConstraint * (^)(MASLayoutPriority))priority {
72 | return ^id(MASLayoutPriority priority) {
73 | for (MASConstraint *constraint in self.childConstraints) {
74 | constraint.priority(priority);
75 | }
76 | return self;
77 | };
78 | }
79 |
80 | #pragma mark - NSLayoutRelation proxy
81 |
82 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
83 | return ^id(id attr, NSLayoutRelation relation) {
84 | for (MASConstraint *constraint in self.childConstraints.copy) {
85 | constraint.equalToWithRelation(attr, relation);
86 | }
87 | return self;
88 | };
89 | }
90 |
91 | #pragma mark - attribute chaining
92 |
93 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
94 | [self constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
95 | return self;
96 | }
97 |
98 | #pragma mark - Animator proxy
99 |
100 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE
101 |
102 | - (MASConstraint *)animator {
103 | for (MASConstraint *constraint in self.childConstraints) {
104 | [constraint animator];
105 | }
106 | return self;
107 | }
108 |
109 | #endif
110 |
111 | #pragma mark - debug helpers
112 |
113 | - (MASConstraint * (^)(id))key {
114 | return ^id(id key) {
115 | self.mas_key = key;
116 | int i = 0;
117 | for (MASConstraint *constraint in self.childConstraints) {
118 | constraint.key([NSString stringWithFormat:@"%@[%d]", key, i++]);
119 | }
120 | return self;
121 | };
122 | }
123 |
124 | #pragma mark - NSLayoutConstraint constant setters
125 |
126 | - (void)setInsets:(MASEdgeInsets)insets {
127 | for (MASConstraint *constraint in self.childConstraints) {
128 | constraint.insets = insets;
129 | }
130 | }
131 |
132 | - (void)setOffset:(CGFloat)offset {
133 | for (MASConstraint *constraint in self.childConstraints) {
134 | constraint.offset = offset;
135 | }
136 | }
137 |
138 | - (void)setSizeOffset:(CGSize)sizeOffset {
139 | for (MASConstraint *constraint in self.childConstraints) {
140 | constraint.sizeOffset = sizeOffset;
141 | }
142 | }
143 |
144 | - (void)setCenterOffset:(CGPoint)centerOffset {
145 | for (MASConstraint *constraint in self.childConstraints) {
146 | constraint.centerOffset = centerOffset;
147 | }
148 | }
149 |
150 | #pragma mark - MASConstraint
151 |
152 | - (void)activate {
153 | for (MASConstraint *constraint in self.childConstraints) {
154 | [constraint activate];
155 | }
156 | }
157 |
158 | - (void)deactivate {
159 | for (MASConstraint *constraint in self.childConstraints) {
160 | [constraint deactivate];
161 | }
162 | }
163 |
164 | - (void)install {
165 | for (MASConstraint *constraint in self.childConstraints) {
166 | constraint.updateExisting = self.updateExisting;
167 | [constraint install];
168 | }
169 | }
170 |
171 | - (void)uninstall {
172 | for (MASConstraint *constraint in self.childConstraints) {
173 | [constraint uninstall];
174 | }
175 | }
176 |
177 | @end
178 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASConstraint+Private.h:
--------------------------------------------------------------------------------
1 | //
2 | // MASConstraint+Private.h
3 | // Masonry
4 | //
5 | // Created by Nick Tymchenko on 29/04/14.
6 | // Copyright (c) 2014 cloudling. All rights reserved.
7 | //
8 |
9 | #import "MASConstraint.h"
10 |
11 | @protocol MASConstraintDelegate;
12 |
13 |
14 | @interface MASConstraint ()
15 |
16 | /**
17 | * Whether or not to check for an existing constraint instead of adding constraint
18 | */
19 | @property (nonatomic, assign) BOOL updateExisting;
20 |
21 | /**
22 | * Usually MASConstraintMaker but could be a parent MASConstraint
23 | */
24 | @property (nonatomic, weak) id delegate;
25 |
26 | /**
27 | * Based on a provided value type, is equal to calling:
28 | * NSNumber - setOffset:
29 | * NSValue with CGPoint - setPointOffset:
30 | * NSValue with CGSize - setSizeOffset:
31 | * NSValue with MASEdgeInsets - setInsets:
32 | */
33 | - (void)setLayoutConstantWithValue:(NSValue *)value;
34 |
35 | @end
36 |
37 |
38 | @interface MASConstraint (Abstract)
39 |
40 | /**
41 | * Sets the constraint relation to given NSLayoutRelation
42 | * returns a block which accepts one of the following:
43 | * MASViewAttribute, UIView, NSValue, NSArray
44 | * see readme for more details.
45 | */
46 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation;
47 |
48 | /**
49 | * Override to set a custom chaining behaviour
50 | */
51 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute;
52 |
53 | @end
54 |
55 |
56 | @protocol MASConstraintDelegate
57 |
58 | /**
59 | * Notifies the delegate when the constraint needs to be replaced with another constraint. For example
60 | * A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks
61 | */
62 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint;
63 |
64 | - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute;
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASConstraint.h:
--------------------------------------------------------------------------------
1 | //
2 | // MASConstraint.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 22/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import "MASUtilities.h"
10 |
11 | /**
12 | * Enables Constraints to be created with chainable syntax
13 | * Constraint can represent single NSLayoutConstraint (MASViewConstraint)
14 | * or a group of NSLayoutConstraints (MASComposisteConstraint)
15 | */
16 | @interface MASConstraint : NSObject
17 |
18 | // Chaining Support
19 |
20 | /**
21 | * Modifies the NSLayoutConstraint constant,
22 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
23 | * NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
24 | */
25 | - (MASConstraint * (^)(MASEdgeInsets insets))insets;
26 |
27 | /**
28 | * Modifies the NSLayoutConstraint constant,
29 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
30 | * NSLayoutAttributeWidth, NSLayoutAttributeHeight
31 | */
32 | - (MASConstraint * (^)(CGSize offset))sizeOffset;
33 |
34 | /**
35 | * Modifies the NSLayoutConstraint constant,
36 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
37 | * NSLayoutAttributeCenterX, NSLayoutAttributeCenterY
38 | */
39 | - (MASConstraint * (^)(CGPoint offset))centerOffset;
40 |
41 | /**
42 | * Modifies the NSLayoutConstraint constant
43 | */
44 | - (MASConstraint * (^)(CGFloat offset))offset;
45 |
46 | /**
47 | * Modifies the NSLayoutConstraint constant based on a value type
48 | */
49 | - (MASConstraint * (^)(NSValue *value))valueOffset;
50 |
51 | /**
52 | * Sets the NSLayoutConstraint multiplier property
53 | */
54 | - (MASConstraint * (^)(CGFloat multiplier))multipliedBy;
55 |
56 | /**
57 | * Sets the NSLayoutConstraint multiplier to 1.0/dividedBy
58 | */
59 | - (MASConstraint * (^)(CGFloat divider))dividedBy;
60 |
61 | /**
62 | * Sets the NSLayoutConstraint priority to a float or MASLayoutPriority
63 | */
64 | - (MASConstraint * (^)(MASLayoutPriority priority))priority;
65 |
66 | /**
67 | * Sets the NSLayoutConstraint priority to MASLayoutPriorityLow
68 | */
69 | - (MASConstraint * (^)())priorityLow;
70 |
71 | /**
72 | * Sets the NSLayoutConstraint priority to MASLayoutPriorityMedium
73 | */
74 | - (MASConstraint * (^)())priorityMedium;
75 |
76 | /**
77 | * Sets the NSLayoutConstraint priority to MASLayoutPriorityHigh
78 | */
79 | - (MASConstraint * (^)())priorityHigh;
80 |
81 | /**
82 | * Sets the constraint relation to NSLayoutRelationEqual
83 | * returns a block which accepts one of the following:
84 | * MASViewAttribute, UIView, NSValue, NSArray
85 | * see readme for more details.
86 | */
87 | - (MASConstraint * (^)(id attr))equalTo;
88 |
89 | /**
90 | * Sets the constraint relation to NSLayoutRelationGreaterThanOrEqual
91 | * returns a block which accepts one of the following:
92 | * MASViewAttribute, UIView, NSValue, NSArray
93 | * see readme for more details.
94 | */
95 | - (MASConstraint * (^)(id attr))greaterThanOrEqualTo;
96 |
97 | /**
98 | * Sets the constraint relation to NSLayoutRelationLessThanOrEqual
99 | * returns a block which accepts one of the following:
100 | * MASViewAttribute, UIView, NSValue, NSArray
101 | * see readme for more details.
102 | */
103 | - (MASConstraint * (^)(id attr))lessThanOrEqualTo;
104 |
105 | /**
106 | * Optional semantic property which has no effect but improves the readability of constraint
107 | */
108 | - (MASConstraint *)with;
109 |
110 | /**
111 | * Optional semantic property which has no effect but improves the readability of constraint
112 | */
113 | - (MASConstraint *)and;
114 |
115 | /**
116 | * Creates a new MASCompositeConstraint with the called attribute and reciever
117 | */
118 | - (MASConstraint *)left;
119 | - (MASConstraint *)top;
120 | - (MASConstraint *)right;
121 | - (MASConstraint *)bottom;
122 | - (MASConstraint *)leading;
123 | - (MASConstraint *)trailing;
124 | - (MASConstraint *)width;
125 | - (MASConstraint *)height;
126 | - (MASConstraint *)centerX;
127 | - (MASConstraint *)centerY;
128 | - (MASConstraint *)baseline;
129 |
130 | #if TARGET_OS_IPHONE
131 |
132 | - (MASConstraint *)leftMargin;
133 | - (MASConstraint *)rightMargin;
134 | - (MASConstraint *)topMargin;
135 | - (MASConstraint *)bottomMargin;
136 | - (MASConstraint *)leadingMargin;
137 | - (MASConstraint *)trailingMargin;
138 | - (MASConstraint *)centerXWithinMargins;
139 | - (MASConstraint *)centerYWithinMargins;
140 |
141 | #endif
142 |
143 |
144 | /**
145 | * Sets the constraint debug name
146 | */
147 | - (MASConstraint * (^)(id key))key;
148 |
149 | // NSLayoutConstraint constant Setters
150 | // for use outside of mas_updateConstraints/mas_makeConstraints blocks
151 |
152 | /**
153 | * Modifies the NSLayoutConstraint constant,
154 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
155 | * NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
156 | */
157 | - (void)setInsets:(MASEdgeInsets)insets;
158 |
159 | /**
160 | * Modifies the NSLayoutConstraint constant,
161 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
162 | * NSLayoutAttributeWidth, NSLayoutAttributeHeight
163 | */
164 | - (void)setSizeOffset:(CGSize)sizeOffset;
165 |
166 | /**
167 | * Modifies the NSLayoutConstraint constant,
168 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
169 | * NSLayoutAttributeCenterX, NSLayoutAttributeCenterY
170 | */
171 | - (void)setCenterOffset:(CGPoint)centerOffset;
172 |
173 | /**
174 | * Modifies the NSLayoutConstraint constant
175 | */
176 | - (void)setOffset:(CGFloat)offset;
177 |
178 |
179 | // NSLayoutConstraint Installation support
180 |
181 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE
182 | /**
183 | * Whether or not to go through the animator proxy when modifying the constraint
184 | */
185 | @property (nonatomic, copy, readonly) MASConstraint *animator;
186 | #endif
187 |
188 | /**
189 | * Activates an NSLayoutConstraint if it's supported by an OS.
190 | * Invokes install otherwise.
191 | */
192 | - (void)activate;
193 |
194 | /**
195 | * Deactivates previously installed/activated NSLayoutConstraint.
196 | */
197 | - (void)deactivate;
198 |
199 | /**
200 | * Creates a NSLayoutConstraint and adds it to the appropriate view.
201 | */
202 | - (void)install;
203 |
204 | /**
205 | * Removes previously installed NSLayoutConstraint
206 | */
207 | - (void)uninstall;
208 |
209 | @end
210 |
211 |
212 | /**
213 | * Convenience auto-boxing macros for MASConstraint methods.
214 | *
215 | * Defining MAS_SHORTHAND_GLOBALS will turn on auto-boxing for default syntax.
216 | * A potential drawback of this is that the unprefixed macros will appear in global scope.
217 | */
218 | #define mas_equalTo(...) equalTo(MASBoxValue((__VA_ARGS__)))
219 | #define mas_greaterThanOrEqualTo(...) greaterThanOrEqualTo(MASBoxValue((__VA_ARGS__)))
220 | #define mas_lessThanOrEqualTo(...) lessThanOrEqualTo(MASBoxValue((__VA_ARGS__)))
221 |
222 | #define mas_offset(...) valueOffset(MASBoxValue((__VA_ARGS__)))
223 |
224 |
225 | #ifdef MAS_SHORTHAND_GLOBALS
226 |
227 | #define equalTo(...) mas_equalTo(__VA_ARGS__)
228 | #define greaterThanOrEqualTo(...) mas_greaterThanOrEqualTo(__VA_ARGS__)
229 | #define lessThanOrEqualTo(...) mas_lessThanOrEqualTo(__VA_ARGS__)
230 |
231 | #define offset(...) mas_offset(__VA_ARGS__)
232 |
233 | #endif
234 |
235 |
236 | @interface MASConstraint (AutoboxingSupport)
237 |
238 | /**
239 | * Aliases to corresponding relation methods (for shorthand macros)
240 | * Also needed to aid autocompletion
241 | */
242 | - (MASConstraint * (^)(id attr))mas_equalTo;
243 | - (MASConstraint * (^)(id attr))mas_greaterThanOrEqualTo;
244 | - (MASConstraint * (^)(id attr))mas_lessThanOrEqualTo;
245 |
246 | /**
247 | * A dummy method to aid autocompletion
248 | */
249 | - (MASConstraint * (^)(id offset))mas_offset;
250 |
251 | @end
252 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASConstraint.m:
--------------------------------------------------------------------------------
1 | //
2 | // MASConstraint.m
3 | // Masonry
4 | //
5 | // Created by Nick Tymchenko on 1/20/14.
6 | //
7 |
8 | #import "MASConstraint.h"
9 | #import "MASConstraint+Private.h"
10 |
11 | #define MASMethodNotImplemented() \
12 | @throw [NSException exceptionWithName:NSInternalInconsistencyException \
13 | reason:[NSString stringWithFormat:@"You must override %@ in a subclass.", NSStringFromSelector(_cmd)] \
14 | userInfo:nil]
15 |
16 | @implementation MASConstraint
17 |
18 | #pragma mark - Init
19 |
20 | - (id)init {
21 | NSAssert(![self isMemberOfClass:[MASConstraint class]], @"MASConstraint is an abstract class, you should not instantiate it directly.");
22 | return [super init];
23 | }
24 |
25 | #pragma mark - NSLayoutRelation proxies
26 |
27 | - (MASConstraint * (^)(id))equalTo {
28 | return ^id(id attribute) {
29 | return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
30 | };
31 | }
32 |
33 | - (MASConstraint * (^)(id))mas_equalTo {
34 | return ^id(id attribute) {
35 | return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
36 | };
37 | }
38 |
39 | - (MASConstraint * (^)(id))greaterThanOrEqualTo {
40 | return ^id(id attribute) {
41 | return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual);
42 | };
43 | }
44 |
45 | - (MASConstraint * (^)(id))mas_greaterThanOrEqualTo {
46 | return ^id(id attribute) {
47 | return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual);
48 | };
49 | }
50 |
51 | - (MASConstraint * (^)(id))lessThanOrEqualTo {
52 | return ^id(id attribute) {
53 | return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual);
54 | };
55 | }
56 |
57 | - (MASConstraint * (^)(id))mas_lessThanOrEqualTo {
58 | return ^id(id attribute) {
59 | return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual);
60 | };
61 | }
62 |
63 | #pragma mark - MASLayoutPriority proxies
64 |
65 | - (MASConstraint * (^)())priorityLow {
66 | return ^id{
67 | self.priority(MASLayoutPriorityDefaultLow);
68 | return self;
69 | };
70 | }
71 |
72 | - (MASConstraint * (^)())priorityMedium {
73 | return ^id{
74 | self.priority(MASLayoutPriorityDefaultMedium);
75 | return self;
76 | };
77 | }
78 |
79 | - (MASConstraint * (^)())priorityHigh {
80 | return ^id{
81 | self.priority(MASLayoutPriorityDefaultHigh);
82 | return self;
83 | };
84 | }
85 |
86 | #pragma mark - NSLayoutConstraint constant proxies
87 |
88 | - (MASConstraint * (^)(MASEdgeInsets))insets {
89 | return ^id(MASEdgeInsets insets){
90 | self.insets = insets;
91 | return self;
92 | };
93 | }
94 |
95 | - (MASConstraint * (^)(CGSize))sizeOffset {
96 | return ^id(CGSize offset) {
97 | self.sizeOffset = offset;
98 | return self;
99 | };
100 | }
101 |
102 | - (MASConstraint * (^)(CGPoint))centerOffset {
103 | return ^id(CGPoint offset) {
104 | self.centerOffset = offset;
105 | return self;
106 | };
107 | }
108 |
109 | - (MASConstraint * (^)(CGFloat))offset {
110 | return ^id(CGFloat offset){
111 | self.offset = offset;
112 | return self;
113 | };
114 | }
115 |
116 | - (MASConstraint * (^)(NSValue *value))valueOffset {
117 | return ^id(NSValue *offset) {
118 | NSAssert([offset isKindOfClass:NSValue.class], @"expected an NSValue offset, got: %@", offset);
119 | [self setLayoutConstantWithValue:offset];
120 | return self;
121 | };
122 | }
123 |
124 | - (MASConstraint * (^)(id offset))mas_offset {
125 | // Will never be called due to macro
126 | return nil;
127 | }
128 |
129 | #pragma mark - NSLayoutConstraint constant setter
130 |
131 | - (void)setLayoutConstantWithValue:(NSValue *)value {
132 | if ([value isKindOfClass:NSNumber.class]) {
133 | self.offset = [(NSNumber *)value doubleValue];
134 | } else if (strcmp(value.objCType, @encode(CGPoint)) == 0) {
135 | CGPoint point;
136 | [value getValue:&point];
137 | self.centerOffset = point;
138 | } else if (strcmp(value.objCType, @encode(CGSize)) == 0) {
139 | CGSize size;
140 | [value getValue:&size];
141 | self.sizeOffset = size;
142 | } else if (strcmp(value.objCType, @encode(MASEdgeInsets)) == 0) {
143 | MASEdgeInsets insets;
144 | [value getValue:&insets];
145 | self.insets = insets;
146 | } else {
147 | NSAssert(NO, @"attempting to set layout constant with unsupported value: %@", value);
148 | }
149 | }
150 |
151 | #pragma mark - Semantic properties
152 |
153 | - (MASConstraint *)with {
154 | return self;
155 | }
156 |
157 | - (MASConstraint *)and {
158 | return self;
159 | }
160 |
161 | #pragma mark - Chaining
162 |
163 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute __unused)layoutAttribute {
164 | MASMethodNotImplemented();
165 | }
166 |
167 | - (MASConstraint *)left {
168 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
169 | }
170 |
171 | - (MASConstraint *)top {
172 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop];
173 | }
174 |
175 | - (MASConstraint *)right {
176 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight];
177 | }
178 |
179 | - (MASConstraint *)bottom {
180 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom];
181 | }
182 |
183 | - (MASConstraint *)leading {
184 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading];
185 | }
186 |
187 | - (MASConstraint *)trailing {
188 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing];
189 | }
190 |
191 | - (MASConstraint *)width {
192 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth];
193 | }
194 |
195 | - (MASConstraint *)height {
196 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight];
197 | }
198 |
199 | - (MASConstraint *)centerX {
200 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX];
201 | }
202 |
203 | - (MASConstraint *)centerY {
204 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY];
205 | }
206 |
207 | - (MASConstraint *)baseline {
208 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline];
209 | }
210 |
211 | #if TARGET_OS_IPHONE
212 |
213 | - (MASConstraint *)leftMargin {
214 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin];
215 | }
216 |
217 | - (MASConstraint *)rightMargin {
218 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin];
219 | }
220 |
221 | - (MASConstraint *)topMargin {
222 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin];
223 | }
224 |
225 | - (MASConstraint *)bottomMargin {
226 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin];
227 | }
228 |
229 | - (MASConstraint *)leadingMargin {
230 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin];
231 | }
232 |
233 | - (MASConstraint *)trailingMargin {
234 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin];
235 | }
236 |
237 | - (MASConstraint *)centerXWithinMargins {
238 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins];
239 | }
240 |
241 | - (MASConstraint *)centerYWithinMargins {
242 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins];
243 | }
244 |
245 | #endif
246 |
247 | #pragma mark - Abstract
248 |
249 | - (MASConstraint * (^)(CGFloat multiplier))multipliedBy { MASMethodNotImplemented(); }
250 |
251 | - (MASConstraint * (^)(CGFloat divider))dividedBy { MASMethodNotImplemented(); }
252 |
253 | - (MASConstraint * (^)(MASLayoutPriority priority))priority { MASMethodNotImplemented(); }
254 |
255 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { MASMethodNotImplemented(); }
256 |
257 | - (MASConstraint * (^)(id key))key { MASMethodNotImplemented(); }
258 |
259 | - (void)setInsets:(MASEdgeInsets __unused)insets { MASMethodNotImplemented(); }
260 |
261 | - (void)setSizeOffset:(CGSize __unused)sizeOffset { MASMethodNotImplemented(); }
262 |
263 | - (void)setCenterOffset:(CGPoint __unused)centerOffset { MASMethodNotImplemented(); }
264 |
265 | - (void)setOffset:(CGFloat __unused)offset { MASMethodNotImplemented(); }
266 |
267 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE
268 |
269 | - (MASConstraint *)animator { MASMethodNotImplemented(); }
270 |
271 | #endif
272 |
273 | - (void)activate { MASMethodNotImplemented(); }
274 |
275 | - (void)deactivate { MASMethodNotImplemented(); }
276 |
277 | - (void)install { MASMethodNotImplemented(); }
278 |
279 | - (void)uninstall { MASMethodNotImplemented(); }
280 |
281 | @end
282 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASConstraintMaker.h:
--------------------------------------------------------------------------------
1 | //
2 | // MASConstraintBuilder.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 20/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import "MASConstraint.h"
10 | #import "MASUtilities.h"
11 |
12 | typedef NS_OPTIONS(NSInteger, MASAttribute) {
13 | MASAttributeLeft = 1 << NSLayoutAttributeLeft,
14 | MASAttributeRight = 1 << NSLayoutAttributeRight,
15 | MASAttributeTop = 1 << NSLayoutAttributeTop,
16 | MASAttributeBottom = 1 << NSLayoutAttributeBottom,
17 | MASAttributeLeading = 1 << NSLayoutAttributeLeading,
18 | MASAttributeTrailing = 1 << NSLayoutAttributeTrailing,
19 | MASAttributeWidth = 1 << NSLayoutAttributeWidth,
20 | MASAttributeHeight = 1 << NSLayoutAttributeHeight,
21 | MASAttributeCenterX = 1 << NSLayoutAttributeCenterX,
22 | MASAttributeCenterY = 1 << NSLayoutAttributeCenterY,
23 | MASAttributeBaseline = 1 << NSLayoutAttributeBaseline,
24 |
25 | #if TARGET_OS_IPHONE
26 |
27 | MASAttributeLeftMargin = 1 << NSLayoutAttributeLeftMargin,
28 | MASAttributeRightMargin = 1 << NSLayoutAttributeRightMargin,
29 | MASAttributeTopMargin = 1 << NSLayoutAttributeTopMargin,
30 | MASAttributeBottomMargin = 1 << NSLayoutAttributeBottomMargin,
31 | MASAttributeLeadingMargin = 1 << NSLayoutAttributeLeadingMargin,
32 | MASAttributeTrailingMargin = 1 << NSLayoutAttributeTrailingMargin,
33 | MASAttributeCenterXWithinMargins = 1 << NSLayoutAttributeCenterXWithinMargins,
34 | MASAttributeCenterYWithinMargins = 1 << NSLayoutAttributeCenterYWithinMargins,
35 |
36 | #endif
37 |
38 | };
39 |
40 | /**
41 | * Provides factory methods for creating MASConstraints.
42 | * Constraints are collected until they are ready to be installed
43 | *
44 | */
45 | @interface MASConstraintMaker : NSObject
46 |
47 | /**
48 | * The following properties return a new MASViewConstraint
49 | * with the first item set to the makers associated view and the appropriate MASViewAttribute
50 | */
51 | @property (nonatomic, strong, readonly) MASConstraint *left;
52 | @property (nonatomic, strong, readonly) MASConstraint *top;
53 | @property (nonatomic, strong, readonly) MASConstraint *right;
54 | @property (nonatomic, strong, readonly) MASConstraint *bottom;
55 | @property (nonatomic, strong, readonly) MASConstraint *leading;
56 | @property (nonatomic, strong, readonly) MASConstraint *trailing;
57 | @property (nonatomic, strong, readonly) MASConstraint *width;
58 | @property (nonatomic, strong, readonly) MASConstraint *height;
59 | @property (nonatomic, strong, readonly) MASConstraint *centerX;
60 | @property (nonatomic, strong, readonly) MASConstraint *centerY;
61 | @property (nonatomic, strong, readonly) MASConstraint *baseline;
62 |
63 | #if TARGET_OS_IPHONE
64 |
65 | @property (nonatomic, strong, readonly) MASConstraint *leftMargin;
66 | @property (nonatomic, strong, readonly) MASConstraint *rightMargin;
67 | @property (nonatomic, strong, readonly) MASConstraint *topMargin;
68 | @property (nonatomic, strong, readonly) MASConstraint *bottomMargin;
69 | @property (nonatomic, strong, readonly) MASConstraint *leadingMargin;
70 | @property (nonatomic, strong, readonly) MASConstraint *trailingMargin;
71 | @property (nonatomic, strong, readonly) MASConstraint *centerXWithinMargins;
72 | @property (nonatomic, strong, readonly) MASConstraint *centerYWithinMargins;
73 |
74 | #endif
75 |
76 | /**
77 | * Returns a block which creates a new MASCompositeConstraint with the first item set
78 | * to the makers associated view and children corresponding to the set bits in the
79 | * MASAttribute parameter. Combine multiple attributes via binary-or.
80 | */
81 | @property (nonatomic, strong, readonly) MASConstraint *(^attributes)(MASAttribute attrs);
82 |
83 | /**
84 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeEdges
85 | * which generates the appropriate MASViewConstraint children (top, left, bottom, right)
86 | * with the first item set to the makers associated view
87 | */
88 | @property (nonatomic, strong, readonly) MASConstraint *edges;
89 |
90 | /**
91 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeSize
92 | * which generates the appropriate MASViewConstraint children (width, height)
93 | * with the first item set to the makers associated view
94 | */
95 | @property (nonatomic, strong, readonly) MASConstraint *size;
96 |
97 | /**
98 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeCenter
99 | * which generates the appropriate MASViewConstraint children (centerX, centerY)
100 | * with the first item set to the makers associated view
101 | */
102 | @property (nonatomic, strong, readonly) MASConstraint *center;
103 |
104 | /**
105 | * Whether or not to check for an existing constraint instead of adding constraint
106 | */
107 | @property (nonatomic, assign) BOOL updateExisting;
108 |
109 | /**
110 | * Whether or not to remove existing constraints prior to installing
111 | */
112 | @property (nonatomic, assign) BOOL removeExisting;
113 |
114 | /**
115 | * initialises the maker with a default view
116 | *
117 | * @param view any MASConstrait are created with this view as the first item
118 | *
119 | * @return a new MASConstraintMaker
120 | */
121 | - (id)initWithView:(MAS_VIEW *)view;
122 |
123 | /**
124 | * Calls install method on any MASConstraints which have been created by this maker
125 | *
126 | * @return an array of all the installed MASConstraints
127 | */
128 | - (NSArray *)install;
129 |
130 | - (MASConstraint * (^)(dispatch_block_t))group;
131 |
132 | @end
133 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASConstraintMaker.m:
--------------------------------------------------------------------------------
1 | //
2 | // MASConstraintBuilder.m
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 20/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import "MASConstraintMaker.h"
10 | #import "MASViewConstraint.h"
11 | #import "MASCompositeConstraint.h"
12 | #import "MASConstraint+Private.h"
13 | #import "MASViewAttribute.h"
14 | #import "View+MASAdditions.h"
15 |
16 | @interface MASConstraintMaker ()
17 |
18 | @property (nonatomic, weak) MAS_VIEW *view;
19 | @property (nonatomic, strong) NSMutableArray *constraints;
20 |
21 | @end
22 |
23 | @implementation MASConstraintMaker
24 |
25 | - (id)initWithView:(MAS_VIEW *)view {
26 | self = [super init];
27 | if (!self) return nil;
28 |
29 | self.view = view;
30 | self.constraints = NSMutableArray.new;
31 |
32 | return self;
33 | }
34 |
35 | - (NSArray *)install {
36 | if (self.removeExisting) {
37 | NSArray *installedConstraints = [MASViewConstraint installedConstraintsForView:self.view];
38 | for (MASConstraint *constraint in installedConstraints) {
39 | [constraint uninstall];
40 | }
41 | }
42 | NSArray *constraints = self.constraints.copy;
43 | for (MASConstraint *constraint in constraints) {
44 | constraint.updateExisting = self.updateExisting;
45 | [constraint install];
46 | }
47 | [self.constraints removeAllObjects];
48 | return constraints;
49 | }
50 |
51 | #pragma mark - MASConstraintDelegate
52 |
53 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint {
54 | NSUInteger index = [self.constraints indexOfObject:constraint];
55 | NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);
56 | [self.constraints replaceObjectAtIndex:index withObject:replacementConstraint];
57 | }
58 |
59 | - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
60 | MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute];
61 | MASViewConstraint *newConstraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute];
62 | if ([constraint isKindOfClass:MASViewConstraint.class]) {
63 | //replace with composite constraint
64 | NSArray *children = @[constraint, newConstraint];
65 | MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children];
66 | compositeConstraint.delegate = self;
67 | [self constraint:constraint shouldBeReplacedWithConstraint:compositeConstraint];
68 | return compositeConstraint;
69 | }
70 | if (!constraint) {
71 | newConstraint.delegate = self;
72 | [self.constraints addObject:newConstraint];
73 | }
74 | return newConstraint;
75 | }
76 |
77 | - (MASConstraint *)addConstraintWithAttributes:(MASAttribute)attrs {
78 | __unused MASAttribute anyAttribute = (MASAttributeLeft | MASAttributeRight | MASAttributeTop | MASAttributeBottom | MASAttributeLeading
79 | | MASAttributeTrailing | MASAttributeWidth | MASAttributeHeight | MASAttributeCenterX
80 | | MASAttributeCenterY | MASAttributeBaseline
81 | #if TARGET_OS_IPHONE
82 | | MASAttributeLeftMargin | MASAttributeRightMargin | MASAttributeTopMargin | MASAttributeBottomMargin
83 | | MASAttributeLeadingMargin | MASAttributeTrailingMargin | MASAttributeCenterXWithinMargins
84 | | MASAttributeCenterYWithinMargins
85 | #endif
86 | );
87 |
88 | NSAssert((attrs & anyAttribute) != 0, @"You didn't pass any attribute to make.attributes(...)");
89 |
90 | NSMutableArray *attributes = [NSMutableArray array];
91 |
92 | if (attrs & MASAttributeLeft) [attributes addObject:self.view.mas_left];
93 | if (attrs & MASAttributeRight) [attributes addObject:self.view.mas_right];
94 | if (attrs & MASAttributeTop) [attributes addObject:self.view.mas_top];
95 | if (attrs & MASAttributeBottom) [attributes addObject:self.view.mas_bottom];
96 | if (attrs & MASAttributeLeading) [attributes addObject:self.view.mas_leading];
97 | if (attrs & MASAttributeTrailing) [attributes addObject:self.view.mas_trailing];
98 | if (attrs & MASAttributeWidth) [attributes addObject:self.view.mas_width];
99 | if (attrs & MASAttributeHeight) [attributes addObject:self.view.mas_height];
100 | if (attrs & MASAttributeCenterX) [attributes addObject:self.view.mas_centerX];
101 | if (attrs & MASAttributeCenterY) [attributes addObject:self.view.mas_centerY];
102 | if (attrs & MASAttributeBaseline) [attributes addObject:self.view.mas_baseline];
103 |
104 | #if TARGET_OS_IPHONE
105 |
106 | if (attrs & MASAttributeLeftMargin) [attributes addObject:self.view.mas_leftMargin];
107 | if (attrs & MASAttributeRightMargin) [attributes addObject:self.view.mas_rightMargin];
108 | if (attrs & MASAttributeTopMargin) [attributes addObject:self.view.mas_topMargin];
109 | if (attrs & MASAttributeBottomMargin) [attributes addObject:self.view.mas_bottomMargin];
110 | if (attrs & MASAttributeLeadingMargin) [attributes addObject:self.view.mas_leadingMargin];
111 | if (attrs & MASAttributeTrailingMargin) [attributes addObject:self.view.mas_trailingMargin];
112 | if (attrs & MASAttributeCenterXWithinMargins) [attributes addObject:self.view.mas_centerXWithinMargins];
113 | if (attrs & MASAttributeCenterYWithinMargins) [attributes addObject:self.view.mas_centerYWithinMargins];
114 |
115 | #endif
116 |
117 | NSMutableArray *children = [NSMutableArray arrayWithCapacity:attributes.count];
118 |
119 | for (MASViewAttribute *a in attributes) {
120 | [children addObject:[[MASViewConstraint alloc] initWithFirstViewAttribute:a]];
121 | }
122 |
123 | MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
124 | constraint.delegate = self;
125 | [self.constraints addObject:constraint];
126 | return constraint;
127 | }
128 |
129 | #pragma mark - standard Attributes
130 |
131 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
132 | return [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute];
133 | }
134 |
135 | - (MASConstraint *)left {
136 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
137 | }
138 |
139 | - (MASConstraint *)top {
140 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop];
141 | }
142 |
143 | - (MASConstraint *)right {
144 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight];
145 | }
146 |
147 | - (MASConstraint *)bottom {
148 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom];
149 | }
150 |
151 | - (MASConstraint *)leading {
152 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading];
153 | }
154 |
155 | - (MASConstraint *)trailing {
156 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing];
157 | }
158 |
159 | - (MASConstraint *)width {
160 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth];
161 | }
162 |
163 | - (MASConstraint *)height {
164 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight];
165 | }
166 |
167 | - (MASConstraint *)centerX {
168 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX];
169 | }
170 |
171 | - (MASConstraint *)centerY {
172 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY];
173 | }
174 |
175 | - (MASConstraint *)baseline {
176 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline];
177 | }
178 |
179 | - (MASConstraint *(^)(MASAttribute))attributes {
180 | return ^(MASAttribute attrs){
181 | return [self addConstraintWithAttributes:attrs];
182 | };
183 | }
184 |
185 | #if TARGET_OS_IPHONE
186 |
187 | - (MASConstraint *)leftMargin {
188 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin];
189 | }
190 |
191 | - (MASConstraint *)rightMargin {
192 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin];
193 | }
194 |
195 | - (MASConstraint *)topMargin {
196 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin];
197 | }
198 |
199 | - (MASConstraint *)bottomMargin {
200 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin];
201 | }
202 |
203 | - (MASConstraint *)leadingMargin {
204 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin];
205 | }
206 |
207 | - (MASConstraint *)trailingMargin {
208 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin];
209 | }
210 |
211 | - (MASConstraint *)centerXWithinMargins {
212 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins];
213 | }
214 |
215 | - (MASConstraint *)centerYWithinMargins {
216 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins];
217 | }
218 |
219 | #endif
220 |
221 |
222 | #pragma mark - composite Attributes
223 |
224 | - (MASConstraint *)edges {
225 | return [self addConstraintWithAttributes:MASAttributeTop | MASAttributeLeft | MASAttributeRight | MASAttributeBottom];
226 | }
227 |
228 | - (MASConstraint *)size {
229 | return [self addConstraintWithAttributes:MASAttributeWidth | MASAttributeHeight];
230 | }
231 |
232 | - (MASConstraint *)center {
233 | return [self addConstraintWithAttributes:MASAttributeCenterX | MASAttributeCenterY];
234 | }
235 |
236 | #pragma mark - grouping
237 |
238 | - (MASConstraint *(^)(dispatch_block_t group))group {
239 | return ^id(dispatch_block_t group) {
240 | NSInteger previousCount = self.constraints.count;
241 | group();
242 |
243 | NSArray *children = [self.constraints subarrayWithRange:NSMakeRange(previousCount, self.constraints.count - previousCount)];
244 | MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
245 | constraint.delegate = self;
246 | return constraint;
247 | };
248 | }
249 |
250 | @end
251 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASLayoutConstraint.h:
--------------------------------------------------------------------------------
1 | //
2 | // MASLayoutConstraint.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 3/08/13.
6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved.
7 | //
8 |
9 | #import "MASUtilities.h"
10 |
11 | /**
12 | * When you are debugging or printing the constraints attached to a view this subclass
13 | * makes it easier to identify which constraints have been created via Masonry
14 | */
15 | @interface MASLayoutConstraint : NSLayoutConstraint
16 |
17 | /**
18 | * a key to associate with this constraint
19 | */
20 | @property (nonatomic, strong) id mas_key;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASLayoutConstraint.m:
--------------------------------------------------------------------------------
1 | //
2 | // MASLayoutConstraint.m
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 3/08/13.
6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved.
7 | //
8 |
9 | #import "MASLayoutConstraint.h"
10 |
11 | @implementation MASLayoutConstraint
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASUtilities.h:
--------------------------------------------------------------------------------
1 | //
2 | // MASUtilities.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 19/08/13.
6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #if TARGET_OS_IPHONE
12 |
13 | #import
14 | #define MAS_VIEW UIView
15 | #define MAS_VIEW_CONTROLLER UIViewController
16 | #define MASEdgeInsets UIEdgeInsets
17 |
18 | typedef UILayoutPriority MASLayoutPriority;
19 | static const MASLayoutPriority MASLayoutPriorityRequired = UILayoutPriorityRequired;
20 | static const MASLayoutPriority MASLayoutPriorityDefaultHigh = UILayoutPriorityDefaultHigh;
21 | static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 500;
22 | static const MASLayoutPriority MASLayoutPriorityDefaultLow = UILayoutPriorityDefaultLow;
23 | static const MASLayoutPriority MASLayoutPriorityFittingSizeLevel = UILayoutPriorityFittingSizeLevel;
24 |
25 | #elif TARGET_OS_MAC
26 |
27 | #import
28 | #define MAS_VIEW NSView
29 | #define MASEdgeInsets NSEdgeInsets
30 |
31 | typedef NSLayoutPriority MASLayoutPriority;
32 | static const MASLayoutPriority MASLayoutPriorityRequired = NSLayoutPriorityRequired;
33 | static const MASLayoutPriority MASLayoutPriorityDefaultHigh = NSLayoutPriorityDefaultHigh;
34 | static const MASLayoutPriority MASLayoutPriorityDragThatCanResizeWindow = NSLayoutPriorityDragThatCanResizeWindow;
35 | static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 501;
36 | static const MASLayoutPriority MASLayoutPriorityWindowSizeStayPut = NSLayoutPriorityWindowSizeStayPut;
37 | static const MASLayoutPriority MASLayoutPriorityDragThatCannotResizeWindow = NSLayoutPriorityDragThatCannotResizeWindow;
38 | static const MASLayoutPriority MASLayoutPriorityDefaultLow = NSLayoutPriorityDefaultLow;
39 | static const MASLayoutPriority MASLayoutPriorityFittingSizeCompression = NSLayoutPriorityFittingSizeCompression;
40 |
41 | #endif
42 |
43 | /**
44 | * Allows you to attach keys to objects matching the variable names passed.
45 | *
46 | * view1.mas_key = @"view1", view2.mas_key = @"view2";
47 | *
48 | * is equivalent to:
49 | *
50 | * MASAttachKeys(view1, view2);
51 | */
52 | #define MASAttachKeys(...) \
53 | NSDictionary *keyPairs = NSDictionaryOfVariableBindings(__VA_ARGS__); \
54 | for (id key in keyPairs.allKeys) { \
55 | id obj = keyPairs[key]; \
56 | NSAssert([obj respondsToSelector:@selector(setMas_key:)], \
57 | @"Cannot attach mas_key to %@", obj); \
58 | [obj setMas_key:key]; \
59 | }
60 |
61 | /**
62 | * Used to create object hashes
63 | * Based on http://www.mikeash.com/pyblog/friday-qa-2010-06-18-implementing-equality-and-hashing.html
64 | */
65 | #define MAS_NSUINT_BIT (CHAR_BIT * sizeof(NSUInteger))
66 | #define MAS_NSUINTROTATE(val, howmuch) ((((NSUInteger)val) << howmuch) | (((NSUInteger)val) >> (MAS_NSUINT_BIT - howmuch)))
67 |
68 | /**
69 | * Given a scalar or struct value, wraps it in NSValue
70 | * Based on EXPObjectify: https://github.com/specta/expecta
71 | */
72 | static inline id _MASBoxValue(const char *type, ...) {
73 | va_list v;
74 | va_start(v, type);
75 | id obj = nil;
76 | if (strcmp(type, @encode(id)) == 0) {
77 | id actual = va_arg(v, id);
78 | obj = actual;
79 | } else if (strcmp(type, @encode(CGPoint)) == 0) {
80 | CGPoint actual = (CGPoint)va_arg(v, CGPoint);
81 | obj = [NSValue value:&actual withObjCType:type];
82 | } else if (strcmp(type, @encode(CGSize)) == 0) {
83 | CGSize actual = (CGSize)va_arg(v, CGSize);
84 | obj = [NSValue value:&actual withObjCType:type];
85 | } else if (strcmp(type, @encode(MASEdgeInsets)) == 0) {
86 | MASEdgeInsets actual = (MASEdgeInsets)va_arg(v, MASEdgeInsets);
87 | obj = [NSValue value:&actual withObjCType:type];
88 | } else if (strcmp(type, @encode(double)) == 0) {
89 | double actual = (double)va_arg(v, double);
90 | obj = [NSNumber numberWithDouble:actual];
91 | } else if (strcmp(type, @encode(float)) == 0) {
92 | float actual = (float)va_arg(v, double);
93 | obj = [NSNumber numberWithFloat:actual];
94 | } else if (strcmp(type, @encode(int)) == 0) {
95 | int actual = (int)va_arg(v, int);
96 | obj = [NSNumber numberWithInt:actual];
97 | } else if (strcmp(type, @encode(long)) == 0) {
98 | long actual = (long)va_arg(v, long);
99 | obj = [NSNumber numberWithLong:actual];
100 | } else if (strcmp(type, @encode(long long)) == 0) {
101 | long long actual = (long long)va_arg(v, long long);
102 | obj = [NSNumber numberWithLongLong:actual];
103 | } else if (strcmp(type, @encode(short)) == 0) {
104 | short actual = (short)va_arg(v, int);
105 | obj = [NSNumber numberWithShort:actual];
106 | } else if (strcmp(type, @encode(char)) == 0) {
107 | char actual = (char)va_arg(v, int);
108 | obj = [NSNumber numberWithChar:actual];
109 | } else if (strcmp(type, @encode(bool)) == 0) {
110 | bool actual = (bool)va_arg(v, int);
111 | obj = [NSNumber numberWithBool:actual];
112 | } else if (strcmp(type, @encode(unsigned char)) == 0) {
113 | unsigned char actual = (unsigned char)va_arg(v, unsigned int);
114 | obj = [NSNumber numberWithUnsignedChar:actual];
115 | } else if (strcmp(type, @encode(unsigned int)) == 0) {
116 | unsigned int actual = (unsigned int)va_arg(v, unsigned int);
117 | obj = [NSNumber numberWithUnsignedInt:actual];
118 | } else if (strcmp(type, @encode(unsigned long)) == 0) {
119 | unsigned long actual = (unsigned long)va_arg(v, unsigned long);
120 | obj = [NSNumber numberWithUnsignedLong:actual];
121 | } else if (strcmp(type, @encode(unsigned long long)) == 0) {
122 | unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long);
123 | obj = [NSNumber numberWithUnsignedLongLong:actual];
124 | } else if (strcmp(type, @encode(unsigned short)) == 0) {
125 | unsigned short actual = (unsigned short)va_arg(v, unsigned int);
126 | obj = [NSNumber numberWithUnsignedShort:actual];
127 | }
128 | va_end(v);
129 | return obj;
130 | }
131 |
132 | #define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value))
133 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASViewAttribute.h:
--------------------------------------------------------------------------------
1 | //
2 | // MASAttribute.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 21/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import "MASUtilities.h"
10 |
11 | /**
12 | * An immutable tuple which stores the view and the related NSLayoutAttribute.
13 | * Describes part of either the left or right hand side of a constraint equation
14 | */
15 | @interface MASViewAttribute : NSObject
16 |
17 | /**
18 | * The view which the reciever relates to. Can be nil if item is not a view.
19 | */
20 | @property (nonatomic, weak, readonly) MAS_VIEW *view;
21 |
22 | /**
23 | * The item which the reciever relates to.
24 | */
25 | @property (nonatomic, weak, readonly) id item;
26 |
27 | /**
28 | * The attribute which the reciever relates to
29 | */
30 | @property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute;
31 |
32 | /**
33 | * Convenience initializer.
34 | */
35 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute;
36 |
37 | /**
38 | * The designated initializer.
39 | */
40 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute;
41 |
42 | /**
43 | * Determine whether the layoutAttribute is a size attribute
44 | *
45 | * @return YES if layoutAttribute is equal to NSLayoutAttributeWidth or NSLayoutAttributeHeight
46 | */
47 | - (BOOL)isSizeAttribute;
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASViewAttribute.m:
--------------------------------------------------------------------------------
1 | //
2 | // MASAttribute.m
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 21/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import "MASViewAttribute.h"
10 |
11 | @implementation MASViewAttribute
12 |
13 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute {
14 | self = [self initWithView:view item:view layoutAttribute:layoutAttribute];
15 | return self;
16 | }
17 |
18 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute {
19 | self = [super init];
20 | if (!self) return nil;
21 |
22 | _view = view;
23 | _item = item;
24 | _layoutAttribute = layoutAttribute;
25 |
26 | return self;
27 | }
28 |
29 | - (BOOL)isSizeAttribute {
30 | return self.layoutAttribute == NSLayoutAttributeWidth
31 | || self.layoutAttribute == NSLayoutAttributeHeight;
32 | }
33 |
34 | - (BOOL)isEqual:(MASViewAttribute *)viewAttribute {
35 | if ([viewAttribute isKindOfClass:self.class]) {
36 | return self.view == viewAttribute.view
37 | && self.layoutAttribute == viewAttribute.layoutAttribute;
38 | }
39 | return [super isEqual:viewAttribute];
40 | }
41 |
42 | - (NSUInteger)hash {
43 | return MAS_NSUINTROTATE([self.view hash], MAS_NSUINT_BIT / 2) ^ self.layoutAttribute;
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASViewConstraint.h:
--------------------------------------------------------------------------------
1 | //
2 | // MASConstraint.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 20/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import "MASViewAttribute.h"
10 | #import "MASConstraint.h"
11 | #import "MASLayoutConstraint.h"
12 | #import "MASUtilities.h"
13 |
14 | /**
15 | * A single constraint.
16 | * Contains the attributes neccessary for creating a NSLayoutConstraint and adding it to the appropriate view
17 | */
18 | @interface MASViewConstraint : MASConstraint
19 |
20 | /**
21 | * First item/view and first attribute of the NSLayoutConstraint
22 | */
23 | @property (nonatomic, strong, readonly) MASViewAttribute *firstViewAttribute;
24 |
25 | /**
26 | * Second item/view and second attribute of the NSLayoutConstraint
27 | */
28 | @property (nonatomic, strong, readonly) MASViewAttribute *secondViewAttribute;
29 |
30 | /**
31 | * initialises the MASViewConstraint with the first part of the equation
32 | *
33 | * @param firstViewAttribute view.mas_left, view.mas_width etc.
34 | *
35 | * @return a new view constraint
36 | */
37 | - (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute;
38 |
39 | /**
40 | * Returns all MASViewConstraints installed with this view as a first item.
41 | *
42 | * @param view A view to retrieve constraints for.
43 | *
44 | * @return An array of MASViewConstraints.
45 | */
46 | + (NSArray *)installedConstraintsForView:(MAS_VIEW *)view;
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/MASViewConstraint.m:
--------------------------------------------------------------------------------
1 | //
2 | // MASConstraint.m
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 20/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import "MASViewConstraint.h"
10 | #import "MASConstraint+Private.h"
11 | #import "MASCompositeConstraint.h"
12 | #import "MASLayoutConstraint.h"
13 | #import "View+MASAdditions.h"
14 | #import
15 |
16 | @interface MAS_VIEW (MASConstraints)
17 |
18 | @property (nonatomic, readonly) NSMutableSet *mas_installedConstraints;
19 |
20 | @end
21 |
22 | @implementation MAS_VIEW (MASConstraints)
23 |
24 | static char kInstalledConstraintsKey;
25 |
26 | - (NSMutableSet *)mas_installedConstraints {
27 | NSMutableSet *constraints = objc_getAssociatedObject(self, &kInstalledConstraintsKey);
28 | if (!constraints) {
29 | constraints = [NSMutableSet set];
30 | objc_setAssociatedObject(self, &kInstalledConstraintsKey, constraints, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
31 | }
32 | return constraints;
33 | }
34 |
35 | @end
36 |
37 |
38 | @interface MASViewConstraint ()
39 |
40 | @property (nonatomic, strong, readwrite) MASViewAttribute *secondViewAttribute;
41 | @property (nonatomic, weak) MAS_VIEW *installedView;
42 | @property (nonatomic, weak) MASLayoutConstraint *layoutConstraint;
43 | @property (nonatomic, assign) NSLayoutRelation layoutRelation;
44 | @property (nonatomic, assign) MASLayoutPriority layoutPriority;
45 | @property (nonatomic, assign) CGFloat layoutMultiplier;
46 | @property (nonatomic, assign) CGFloat layoutConstant;
47 | @property (nonatomic, assign) BOOL hasLayoutRelation;
48 | @property (nonatomic, strong) id mas_key;
49 | @property (nonatomic, assign) BOOL useAnimator;
50 |
51 | @end
52 |
53 | @implementation MASViewConstraint
54 |
55 | - (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute {
56 | self = [super init];
57 | if (!self) return nil;
58 |
59 | _firstViewAttribute = firstViewAttribute;
60 | self.layoutPriority = MASLayoutPriorityRequired;
61 | self.layoutMultiplier = 1;
62 |
63 | return self;
64 | }
65 |
66 | #pragma mark - NSCoping
67 |
68 | - (id)copyWithZone:(NSZone __unused *)zone {
69 | MASViewConstraint *constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:self.firstViewAttribute];
70 | constraint.layoutConstant = self.layoutConstant;
71 | constraint.layoutRelation = self.layoutRelation;
72 | constraint.layoutPriority = self.layoutPriority;
73 | constraint.layoutMultiplier = self.layoutMultiplier;
74 | constraint.delegate = self.delegate;
75 | return constraint;
76 | }
77 |
78 | #pragma mark - Public
79 |
80 | + (NSArray *)installedConstraintsForView:(MAS_VIEW *)view {
81 | return [view.mas_installedConstraints allObjects];
82 | }
83 |
84 | #pragma mark - Private
85 |
86 | - (void)setLayoutConstant:(CGFloat)layoutConstant {
87 | _layoutConstant = layoutConstant;
88 |
89 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE
90 | if (self.useAnimator) {
91 | [self.layoutConstraint.animator setConstant:layoutConstant];
92 | } else {
93 | self.layoutConstraint.constant = layoutConstant;
94 | }
95 | #else
96 | self.layoutConstraint.constant = layoutConstant;
97 | #endif
98 | }
99 |
100 | - (void)setLayoutRelation:(NSLayoutRelation)layoutRelation {
101 | _layoutRelation = layoutRelation;
102 | self.hasLayoutRelation = YES;
103 | }
104 |
105 | - (BOOL)supportsActiveProperty {
106 | return [self.layoutConstraint respondsToSelector:@selector(isActive)];
107 | }
108 |
109 | - (BOOL)isActive {
110 | BOOL active = YES;
111 | if ([self supportsActiveProperty]) {
112 | active = [self.layoutConstraint isActive];
113 | }
114 |
115 | return active;
116 | }
117 |
118 | - (BOOL)hasBeenInstalled {
119 | return (self.layoutConstraint != nil) && [self isActive];
120 | }
121 |
122 | - (void)setSecondViewAttribute:(id)secondViewAttribute {
123 | if ([secondViewAttribute isKindOfClass:NSValue.class]) {
124 | [self setLayoutConstantWithValue:secondViewAttribute];
125 | } else if ([secondViewAttribute isKindOfClass:MAS_VIEW.class]) {
126 | _secondViewAttribute = [[MASViewAttribute alloc] initWithView:secondViewAttribute layoutAttribute:self.firstViewAttribute.layoutAttribute];
127 | } else if ([secondViewAttribute isKindOfClass:MASViewAttribute.class]) {
128 | _secondViewAttribute = secondViewAttribute;
129 | } else {
130 | NSAssert(NO, @"attempting to add unsupported attribute: %@", secondViewAttribute);
131 | }
132 | }
133 |
134 | #pragma mark - NSLayoutConstraint multiplier proxies
135 |
136 | - (MASConstraint * (^)(CGFloat))multipliedBy {
137 | return ^id(CGFloat multiplier) {
138 | NSAssert(!self.hasBeenInstalled,
139 | @"Cannot modify constraint multiplier after it has been installed");
140 |
141 | self.layoutMultiplier = multiplier;
142 | return self;
143 | };
144 | }
145 |
146 |
147 | - (MASConstraint * (^)(CGFloat))dividedBy {
148 | return ^id(CGFloat divider) {
149 | NSAssert(!self.hasBeenInstalled,
150 | @"Cannot modify constraint multiplier after it has been installed");
151 |
152 | self.layoutMultiplier = 1.0/divider;
153 | return self;
154 | };
155 | }
156 |
157 | #pragma mark - MASLayoutPriority proxy
158 |
159 | - (MASConstraint * (^)(MASLayoutPriority))priority {
160 | return ^id(MASLayoutPriority priority) {
161 | NSAssert(!self.hasBeenInstalled,
162 | @"Cannot modify constraint priority after it has been installed");
163 |
164 | self.layoutPriority = priority;
165 | return self;
166 | };
167 | }
168 |
169 | #pragma mark - NSLayoutRelation proxy
170 |
171 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
172 | return ^id(id attribute, NSLayoutRelation relation) {
173 | if ([attribute isKindOfClass:NSArray.class]) {
174 | NSAssert(!self.hasLayoutRelation, @"Redefinition of constraint relation");
175 | NSMutableArray *children = NSMutableArray.new;
176 | for (id attr in attribute) {
177 | MASViewConstraint *viewConstraint = [self copy];
178 | viewConstraint.secondViewAttribute = attr;
179 | [children addObject:viewConstraint];
180 | }
181 | MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children];
182 | compositeConstraint.delegate = self.delegate;
183 | [self.delegate constraint:self shouldBeReplacedWithConstraint:compositeConstraint];
184 | return compositeConstraint;
185 | } else {
186 | NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSValue.class], @"Redefinition of constraint relation");
187 | self.layoutRelation = relation;
188 | self.secondViewAttribute = attribute;
189 | return self;
190 | }
191 | };
192 | }
193 |
194 | #pragma mark - Semantic properties
195 |
196 | - (MASConstraint *)with {
197 | return self;
198 | }
199 |
200 | - (MASConstraint *)and {
201 | return self;
202 | }
203 |
204 | #pragma mark - attribute chaining
205 |
206 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
207 | NSAssert(!self.hasLayoutRelation, @"Attributes should be chained before defining the constraint relation");
208 |
209 | return [self.delegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
210 | }
211 |
212 | #pragma mark - Animator proxy
213 |
214 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE
215 |
216 | - (MASConstraint *)animator {
217 | self.useAnimator = YES;
218 | return self;
219 | }
220 |
221 | #endif
222 |
223 | #pragma mark - debug helpers
224 |
225 | - (MASConstraint * (^)(id))key {
226 | return ^id(id key) {
227 | self.mas_key = key;
228 | return self;
229 | };
230 | }
231 |
232 | #pragma mark - NSLayoutConstraint constant setters
233 |
234 | - (void)setInsets:(MASEdgeInsets)insets {
235 | NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute;
236 | switch (layoutAttribute) {
237 | case NSLayoutAttributeLeft:
238 | case NSLayoutAttributeLeading:
239 | self.layoutConstant = insets.left;
240 | break;
241 | case NSLayoutAttributeTop:
242 | self.layoutConstant = insets.top;
243 | break;
244 | case NSLayoutAttributeBottom:
245 | self.layoutConstant = -insets.bottom;
246 | break;
247 | case NSLayoutAttributeRight:
248 | case NSLayoutAttributeTrailing:
249 | self.layoutConstant = -insets.right;
250 | break;
251 | default:
252 | break;
253 | }
254 | }
255 |
256 | - (void)setOffset:(CGFloat)offset {
257 | self.layoutConstant = offset;
258 | }
259 |
260 | - (void)setSizeOffset:(CGSize)sizeOffset {
261 | NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute;
262 | switch (layoutAttribute) {
263 | case NSLayoutAttributeWidth:
264 | self.layoutConstant = sizeOffset.width;
265 | break;
266 | case NSLayoutAttributeHeight:
267 | self.layoutConstant = sizeOffset.height;
268 | break;
269 | default:
270 | break;
271 | }
272 | }
273 |
274 | - (void)setCenterOffset:(CGPoint)centerOffset {
275 | NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute;
276 | switch (layoutAttribute) {
277 | case NSLayoutAttributeCenterX:
278 | self.layoutConstant = centerOffset.x;
279 | break;
280 | case NSLayoutAttributeCenterY:
281 | self.layoutConstant = centerOffset.y;
282 | break;
283 | default:
284 | break;
285 | }
286 | }
287 |
288 | #pragma mark - MASConstraint
289 |
290 | - (void)activate {
291 | if ([self supportsActiveProperty] && self.layoutConstraint) {
292 | if (self.hasBeenInstalled) {
293 | return;
294 | }
295 | self.layoutConstraint.active = YES;
296 | [self.firstViewAttribute.view.mas_installedConstraints addObject:self];
297 | } else {
298 | [self install];
299 | }
300 | }
301 |
302 | - (void)deactivate {
303 | if ([self supportsActiveProperty]) {
304 | self.layoutConstraint.active = NO;
305 | [self.firstViewAttribute.view.mas_installedConstraints removeObject:self];
306 | } else {
307 | [self uninstall];
308 | }
309 | }
310 |
311 | - (void)install {
312 | if (self.hasBeenInstalled) {
313 | return;
314 | }
315 |
316 | MAS_VIEW *firstLayoutItem = self.firstViewAttribute.item;
317 | NSLayoutAttribute firstLayoutAttribute = self.firstViewAttribute.layoutAttribute;
318 | MAS_VIEW *secondLayoutItem = self.secondViewAttribute.item;
319 | NSLayoutAttribute secondLayoutAttribute = self.secondViewAttribute.layoutAttribute;
320 |
321 | // alignment attributes must have a secondViewAttribute
322 | // therefore we assume that is refering to superview
323 | // eg make.left.equalTo(@10)
324 | if (!self.firstViewAttribute.isSizeAttribute && !self.secondViewAttribute) {
325 | secondLayoutItem = self.firstViewAttribute.view.superview;
326 | secondLayoutAttribute = firstLayoutAttribute;
327 | }
328 |
329 | MASLayoutConstraint *layoutConstraint
330 | = [MASLayoutConstraint constraintWithItem:firstLayoutItem
331 | attribute:firstLayoutAttribute
332 | relatedBy:self.layoutRelation
333 | toItem:secondLayoutItem
334 | attribute:secondLayoutAttribute
335 | multiplier:self.layoutMultiplier
336 | constant:self.layoutConstant];
337 |
338 | layoutConstraint.priority = self.layoutPriority;
339 | layoutConstraint.mas_key = self.mas_key;
340 |
341 | if (self.secondViewAttribute.view) {
342 | MAS_VIEW *closestCommonSuperview = [self.firstViewAttribute.view mas_closestCommonSuperview:self.secondViewAttribute.view];
343 | NSAssert(closestCommonSuperview,
344 | @"couldn't find a common superview for %@ and %@",
345 | self.firstViewAttribute.view, self.secondViewAttribute.view);
346 | self.installedView = closestCommonSuperview;
347 | } else if (self.firstViewAttribute.isSizeAttribute) {
348 | self.installedView = self.firstViewAttribute.view;
349 | } else {
350 | self.installedView = self.firstViewAttribute.view.superview;
351 | }
352 |
353 |
354 | MASLayoutConstraint *existingConstraint = nil;
355 | if (self.updateExisting) {
356 | existingConstraint = [self layoutConstraintSimilarTo:layoutConstraint];
357 | }
358 | if (existingConstraint) {
359 | // just update the constant
360 | existingConstraint.constant = layoutConstraint.constant;
361 | self.layoutConstraint = existingConstraint;
362 | } else {
363 | [self.installedView addConstraint:layoutConstraint];
364 | self.layoutConstraint = layoutConstraint;
365 | [firstLayoutItem.mas_installedConstraints addObject:self];
366 | }
367 | }
368 |
369 | - (MASLayoutConstraint *)layoutConstraintSimilarTo:(MASLayoutConstraint *)layoutConstraint {
370 | // check if any constraints are the same apart from the only mutable property constant
371 |
372 | // go through constraints in reverse as we do not want to match auto-resizing or interface builder constraints
373 | // and they are likely to be added first.
374 | for (NSLayoutConstraint *existingConstraint in self.installedView.constraints.reverseObjectEnumerator) {
375 | if (![existingConstraint isKindOfClass:MASLayoutConstraint.class]) continue;
376 | if (existingConstraint.firstItem != layoutConstraint.firstItem) continue;
377 | if (existingConstraint.secondItem != layoutConstraint.secondItem) continue;
378 | if (existingConstraint.firstAttribute != layoutConstraint.firstAttribute) continue;
379 | if (existingConstraint.secondAttribute != layoutConstraint.secondAttribute) continue;
380 | if (existingConstraint.relation != layoutConstraint.relation) continue;
381 | if (existingConstraint.multiplier != layoutConstraint.multiplier) continue;
382 | if (existingConstraint.priority != layoutConstraint.priority) continue;
383 |
384 | return (id)existingConstraint;
385 | }
386 | return nil;
387 | }
388 |
389 | - (void)uninstall {
390 | [self.installedView removeConstraint:self.layoutConstraint];
391 | self.layoutConstraint = nil;
392 | self.installedView = nil;
393 |
394 | [self.firstViewAttribute.view.mas_installedConstraints removeObject:self];
395 | }
396 |
397 | @end
398 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/Masonry.h:
--------------------------------------------------------------------------------
1 | //
2 | // Masonry.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 20/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for Masonry.
12 | FOUNDATION_EXPORT double MasonryVersionNumber;
13 |
14 | //! Project version string for Masonry.
15 | FOUNDATION_EXPORT const unsigned char MasonryVersionString[];
16 |
17 | #import "MASUtilities.h"
18 | #import "View+MASAdditions.h"
19 | #import "View+MASShorthandAdditions.h"
20 | #import "ViewController+MASAdditions.h"
21 | #import "NSArray+MASAdditions.h"
22 | #import "NSArray+MASShorthandAdditions.h"
23 | #import "MASConstraint.h"
24 | #import "MASCompositeConstraint.h"
25 | #import "MASViewAttribute.h"
26 | #import "MASViewConstraint.h"
27 | #import "MASConstraintMaker.h"
28 | #import "MASLayoutConstraint.h"
29 | #import "NSLayoutConstraint+MASDebugAdditions.h"
30 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/NSArray+MASAdditions.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSArray+MASAdditions.h
3 | //
4 | //
5 | // Created by Daniel Hammond on 11/26/13.
6 | //
7 | //
8 |
9 | #import "MASUtilities.h"
10 | #import "MASConstraintMaker.h"
11 | #import "MASViewAttribute.h"
12 |
13 | typedef NS_ENUM(NSUInteger, MASAxisType) {
14 | MASAxisTypeHorizontal,
15 | MASAxisTypeVertical
16 | };
17 |
18 | @interface NSArray (MASAdditions)
19 |
20 | /**
21 | * Creates a MASConstraintMaker with each view in the callee.
22 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing on each view
23 | *
24 | * @param block scope within which you can build up the constraints which you wish to apply to each view.
25 | *
26 | * @return Array of created MASConstraints
27 | */
28 | - (NSArray *)mas_makeConstraints:(void (^)(MASConstraintMaker *make))block;
29 |
30 | /**
31 | * Creates a MASConstraintMaker with each view in the callee.
32 | * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view.
33 | * If an existing constraint exists then it will be updated instead.
34 | *
35 | * @param block scope within which you can build up the constraints which you wish to apply to each view.
36 | *
37 | * @return Array of created/updated MASConstraints
38 | */
39 | - (NSArray *)mas_updateConstraints:(void (^)(MASConstraintMaker *make))block;
40 |
41 | /**
42 | * Creates a MASConstraintMaker with each view in the callee.
43 | * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view.
44 | * All constraints previously installed for the views will be removed.
45 | *
46 | * @param block scope within which you can build up the constraints which you wish to apply to each view.
47 | *
48 | * @return Array of created/updated MASConstraints
49 | */
50 | - (NSArray *)mas_remakeConstraints:(void (^)(MASConstraintMaker *make))block;
51 |
52 | /**
53 | * distribute with fixed spacing
54 | *
55 | * @param axisType which axis to distribute items along
56 | * @param fixedSpacing the spacing between each item
57 | * @param leadSpacing the spacing before the first item and the container
58 | * @param tailSpacing the spacing after the last item and the container
59 | */
60 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;
61 |
62 | /**
63 | * distribute with fixed item size
64 | *
65 | * @param axisType which axis to distribute items along
66 | * @param fixedItemLength the fixed length of each item
67 | * @param leadSpacing the spacing before the first item and the container
68 | * @param tailSpacing the spacing after the last item and the container
69 | */
70 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/NSArray+MASAdditions.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSArray+MASAdditions.m
3 | //
4 | //
5 | // Created by Daniel Hammond on 11/26/13.
6 | //
7 | //
8 |
9 | #import "NSArray+MASAdditions.h"
10 | #import "View+MASAdditions.h"
11 |
12 | @implementation NSArray (MASAdditions)
13 |
14 | - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block {
15 | NSMutableArray *constraints = [NSMutableArray array];
16 | for (MAS_VIEW *view in self) {
17 | NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views");
18 | [constraints addObjectsFromArray:[view mas_makeConstraints:block]];
19 | }
20 | return constraints;
21 | }
22 |
23 | - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block {
24 | NSMutableArray *constraints = [NSMutableArray array];
25 | for (MAS_VIEW *view in self) {
26 | NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views");
27 | [constraints addObjectsFromArray:[view mas_updateConstraints:block]];
28 | }
29 | return constraints;
30 | }
31 |
32 | - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block {
33 | NSMutableArray *constraints = [NSMutableArray array];
34 | for (MAS_VIEW *view in self) {
35 | NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views");
36 | [constraints addObjectsFromArray:[view mas_remakeConstraints:block]];
37 | }
38 | return constraints;
39 | }
40 |
41 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing {
42 | if (self.count < 2) {
43 | NSAssert(self.count>1,@"views to distribute need to bigger than one");
44 | return;
45 | }
46 |
47 | MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews];
48 | if (axisType == MASAxisTypeHorizontal) {
49 | MAS_VIEW *prev;
50 | for (int i = 0; i < self.count; i++) {
51 | MAS_VIEW *v = self[i];
52 | [v mas_makeConstraints:^(MASConstraintMaker *make) {
53 | if (prev) {
54 | make.width.equalTo(prev);
55 | make.left.equalTo(prev.mas_right).offset(fixedSpacing);
56 | if (i == (CGFloat)self.count - 1) {//last one
57 | make.right.equalTo(tempSuperView).offset(-tailSpacing);
58 | }
59 | }
60 | else {//first one
61 | make.left.equalTo(tempSuperView).offset(leadSpacing);
62 | }
63 |
64 | }];
65 | prev = v;
66 | }
67 | }
68 | else {
69 | MAS_VIEW *prev;
70 | for (int i = 0; i < self.count; i++) {
71 | MAS_VIEW *v = self[i];
72 | [v mas_makeConstraints:^(MASConstraintMaker *make) {
73 | if (prev) {
74 | make.height.equalTo(prev);
75 | make.top.equalTo(prev.mas_bottom).offset(fixedSpacing);
76 | if (i == (CGFloat)self.count - 1) {//last one
77 | make.bottom.equalTo(tempSuperView).offset(-tailSpacing);
78 | }
79 | }
80 | else {//first one
81 | make.top.equalTo(tempSuperView).offset(leadSpacing);
82 | }
83 |
84 | }];
85 | prev = v;
86 | }
87 | }
88 | }
89 |
90 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing {
91 | if (self.count < 2) {
92 | NSAssert(self.count>1,@"views to distribute need to bigger than one");
93 | return;
94 | }
95 |
96 | MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews];
97 | if (axisType == MASAxisTypeHorizontal) {
98 | MAS_VIEW *prev;
99 | for (int i = 0; i < self.count; i++) {
100 | MAS_VIEW *v = self[i];
101 | [v mas_makeConstraints:^(MASConstraintMaker *make) {
102 | if (prev) {
103 | CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1));
104 | make.width.equalTo(@(fixedItemLength));
105 | if (i == (CGFloat)self.count - 1) {//last one
106 | make.right.equalTo(tempSuperView).offset(-tailSpacing);
107 | }
108 | else {
109 | make.right.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset);
110 | }
111 | }
112 | else {//first one
113 | make.left.equalTo(tempSuperView).offset(leadSpacing);
114 | make.width.equalTo(@(fixedItemLength));
115 | }
116 | }];
117 | prev = v;
118 | }
119 | }
120 | else {
121 | MAS_VIEW *prev;
122 | for (int i = 0; i < self.count; i++) {
123 | MAS_VIEW *v = self[i];
124 | [v mas_makeConstraints:^(MASConstraintMaker *make) {
125 | if (prev) {
126 | CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1));
127 | make.height.equalTo(@(fixedItemLength));
128 | if (i == (CGFloat)self.count - 1) {//last one
129 | make.bottom.equalTo(tempSuperView).offset(-tailSpacing);
130 | }
131 | else {
132 | make.bottom.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset);
133 | }
134 | }
135 | else {//first one
136 | make.top.equalTo(tempSuperView).offset(leadSpacing);
137 | make.height.equalTo(@(fixedItemLength));
138 | }
139 | }];
140 | prev = v;
141 | }
142 | }
143 | }
144 |
145 | - (MAS_VIEW *)mas_commonSuperviewOfViews
146 | {
147 | MAS_VIEW *commonSuperview = nil;
148 | MAS_VIEW *previousView = nil;
149 | for (id object in self) {
150 | if ([object isKindOfClass:[MAS_VIEW class]]) {
151 | MAS_VIEW *view = (MAS_VIEW *)object;
152 | if (previousView) {
153 | commonSuperview = [view mas_closestCommonSuperview:commonSuperview];
154 | } else {
155 | commonSuperview = view;
156 | }
157 | previousView = view;
158 | }
159 | }
160 | NSAssert(commonSuperview, @"Can't constrain views that do not share a common superview. Make sure that all the views in this array have been added into the same view hierarchy.");
161 | return commonSuperview;
162 | }
163 |
164 | @end
165 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/NSArray+MASShorthandAdditions.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSArray+MASShorthandAdditions.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 22/07/13.
6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved.
7 | //
8 |
9 | #import "NSArray+MASAdditions.h"
10 |
11 | #ifdef MAS_SHORTHAND
12 |
13 | /**
14 | * Shorthand array additions without the 'mas_' prefixes,
15 | * only enabled if MAS_SHORTHAND is defined
16 | */
17 | @interface NSArray (MASShorthandAdditions)
18 |
19 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block;
20 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block;
21 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block;
22 |
23 | @end
24 |
25 | @implementation NSArray (MASShorthandAdditions)
26 |
27 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block {
28 | return [self mas_makeConstraints:block];
29 | }
30 |
31 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block {
32 | return [self mas_updateConstraints:block];
33 | }
34 |
35 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block {
36 | return [self mas_remakeConstraints:block];
37 | }
38 |
39 | @end
40 |
41 | #endif
42 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/NSLayoutConstraint+MASDebugAdditions.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSLayoutConstraint+MASDebugAdditions.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 3/08/13.
6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved.
7 | //
8 |
9 | #import "MASUtilities.h"
10 |
11 | /**
12 | * makes debug and log output of NSLayoutConstraints more readable
13 | */
14 | @interface NSLayoutConstraint (MASDebugAdditions)
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/NSLayoutConstraint+MASDebugAdditions.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSLayoutConstraint+MASDebugAdditions.m
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 3/08/13.
6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved.
7 | //
8 |
9 | #import "NSLayoutConstraint+MASDebugAdditions.h"
10 | #import "MASConstraint.h"
11 | #import "MASLayoutConstraint.h"
12 |
13 | @implementation NSLayoutConstraint (MASDebugAdditions)
14 |
15 | #pragma mark - description maps
16 |
17 | + (NSDictionary *)layoutRelationDescriptionsByValue {
18 | static dispatch_once_t once;
19 | static NSDictionary *descriptionMap;
20 | dispatch_once(&once, ^{
21 | descriptionMap = @{
22 | @(NSLayoutRelationEqual) : @"==",
23 | @(NSLayoutRelationGreaterThanOrEqual) : @">=",
24 | @(NSLayoutRelationLessThanOrEqual) : @"<=",
25 | };
26 | });
27 | return descriptionMap;
28 | }
29 |
30 | + (NSDictionary *)layoutAttributeDescriptionsByValue {
31 | static dispatch_once_t once;
32 | static NSDictionary *descriptionMap;
33 | dispatch_once(&once, ^{
34 | descriptionMap = @{
35 | @(NSLayoutAttributeTop) : @"top",
36 | @(NSLayoutAttributeLeft) : @"left",
37 | @(NSLayoutAttributeBottom) : @"bottom",
38 | @(NSLayoutAttributeRight) : @"right",
39 | @(NSLayoutAttributeLeading) : @"leading",
40 | @(NSLayoutAttributeTrailing) : @"trailing",
41 | @(NSLayoutAttributeWidth) : @"width",
42 | @(NSLayoutAttributeHeight) : @"height",
43 | @(NSLayoutAttributeCenterX) : @"centerX",
44 | @(NSLayoutAttributeCenterY) : @"centerY",
45 | @(NSLayoutAttributeBaseline) : @"baseline",
46 |
47 | #if TARGET_OS_IPHONE
48 | @(NSLayoutAttributeLeftMargin) : @"leftMargin",
49 | @(NSLayoutAttributeRightMargin) : @"rightMargin",
50 | @(NSLayoutAttributeTopMargin) : @"topMargin",
51 | @(NSLayoutAttributeBottomMargin) : @"bottomMargin",
52 | @(NSLayoutAttributeLeadingMargin) : @"leadingMargin",
53 | @(NSLayoutAttributeTrailingMargin) : @"trailingMargin",
54 | @(NSLayoutAttributeCenterXWithinMargins) : @"centerXWithinMargins",
55 | @(NSLayoutAttributeCenterYWithinMargins) : @"centerYWithinMargins",
56 | #endif
57 |
58 | };
59 |
60 | });
61 | return descriptionMap;
62 | }
63 |
64 |
65 | + (NSDictionary *)layoutPriorityDescriptionsByValue {
66 | static dispatch_once_t once;
67 | static NSDictionary *descriptionMap;
68 | dispatch_once(&once, ^{
69 | #if TARGET_OS_IPHONE
70 | descriptionMap = @{
71 | @(MASLayoutPriorityDefaultHigh) : @"high",
72 | @(MASLayoutPriorityDefaultLow) : @"low",
73 | @(MASLayoutPriorityDefaultMedium) : @"medium",
74 | @(MASLayoutPriorityRequired) : @"required",
75 | @(MASLayoutPriorityFittingSizeLevel) : @"fitting size",
76 | };
77 | #elif TARGET_OS_MAC
78 | descriptionMap = @{
79 | @(MASLayoutPriorityDefaultHigh) : @"high",
80 | @(MASLayoutPriorityDragThatCanResizeWindow) : @"drag can resize window",
81 | @(MASLayoutPriorityDefaultMedium) : @"medium",
82 | @(MASLayoutPriorityWindowSizeStayPut) : @"window size stay put",
83 | @(MASLayoutPriorityDragThatCannotResizeWindow) : @"drag cannot resize window",
84 | @(MASLayoutPriorityDefaultLow) : @"low",
85 | @(MASLayoutPriorityFittingSizeCompression) : @"fitting size",
86 | @(MASLayoutPriorityRequired) : @"required",
87 | };
88 | #endif
89 | });
90 | return descriptionMap;
91 | }
92 |
93 | #pragma mark - description override
94 |
95 | + (NSString *)descriptionForObject:(id)obj {
96 | if ([obj respondsToSelector:@selector(mas_key)] && [obj mas_key]) {
97 | return [NSString stringWithFormat:@"%@:%@", [obj class], [obj mas_key]];
98 | }
99 | return [NSString stringWithFormat:@"%@:%p", [obj class], obj];
100 | }
101 |
102 | - (NSString *)description {
103 | NSMutableString *description = [[NSMutableString alloc] initWithString:@"<"];
104 |
105 | [description appendString:[self.class descriptionForObject:self]];
106 |
107 | [description appendFormat:@" %@", [self.class descriptionForObject:self.firstItem]];
108 | if (self.firstAttribute != NSLayoutAttributeNotAnAttribute) {
109 | [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.firstAttribute)]];
110 | }
111 |
112 | [description appendFormat:@" %@", self.class.layoutRelationDescriptionsByValue[@(self.relation)]];
113 |
114 | if (self.secondItem) {
115 | [description appendFormat:@" %@", [self.class descriptionForObject:self.secondItem]];
116 | }
117 | if (self.secondAttribute != NSLayoutAttributeNotAnAttribute) {
118 | [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.secondAttribute)]];
119 | }
120 |
121 | if (self.multiplier != 1) {
122 | [description appendFormat:@" * %g", self.multiplier];
123 | }
124 |
125 | if (self.secondAttribute == NSLayoutAttributeNotAnAttribute) {
126 | [description appendFormat:@" %g", self.constant];
127 | } else {
128 | if (self.constant) {
129 | [description appendFormat:@" %@ %g", (self.constant < 0 ? @"-" : @"+"), ABS(self.constant)];
130 | }
131 | }
132 |
133 | if (self.priority != MASLayoutPriorityRequired) {
134 | [description appendFormat:@" ^%@", self.class.layoutPriorityDescriptionsByValue[@(self.priority)] ?: [NSNumber numberWithDouble:self.priority]];
135 | }
136 |
137 | [description appendString:@">"];
138 | return description;
139 | }
140 |
141 | @end
142 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/View+MASAdditions.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+MASAdditions.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 20/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import "MASUtilities.h"
10 | #import "MASConstraintMaker.h"
11 | #import "MASViewAttribute.h"
12 |
13 | /**
14 | * Provides constraint maker block
15 | * and convience methods for creating MASViewAttribute which are view + NSLayoutAttribute pairs
16 | */
17 | @interface MAS_VIEW (MASAdditions)
18 |
19 | /**
20 | * following properties return a new MASViewAttribute with current view and appropriate NSLayoutAttribute
21 | */
22 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_left;
23 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_top;
24 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_right;
25 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottom;
26 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leading;
27 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailing;
28 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_width;
29 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_height;
30 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX;
31 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY;
32 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline;
33 | @property (nonatomic, strong, readonly) MASViewAttribute *(^mas_attribute)(NSLayoutAttribute attr);
34 |
35 | #if TARGET_OS_IPHONE
36 |
37 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leftMargin;
38 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_rightMargin;
39 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topMargin;
40 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomMargin;
41 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leadingMargin;
42 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailingMargin;
43 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerXWithinMargins;
44 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerYWithinMargins;
45 |
46 | #endif
47 |
48 | /**
49 | * a key to associate with this view
50 | */
51 | @property (nonatomic, strong) id mas_key;
52 |
53 | /**
54 | * Finds the closest common superview between this view and another view
55 | *
56 | * @param view other view
57 | *
58 | * @return returns nil if common superview could not be found
59 | */
60 | - (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view;
61 |
62 | /**
63 | * Creates a MASConstraintMaker with the callee view.
64 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing
65 | *
66 | * @param block scope within which you can build up the constraints which you wish to apply to the view.
67 | *
68 | * @return Array of created MASConstraints
69 | */
70 | - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;
71 |
72 | /**
73 | * Creates a MASConstraintMaker with the callee view.
74 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing.
75 | * If an existing constraint exists then it will be updated instead.
76 | *
77 | * @param block scope within which you can build up the constraints which you wish to apply to the view.
78 | *
79 | * @return Array of created/updated MASConstraints
80 | */
81 | - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;
82 |
83 | /**
84 | * Creates a MASConstraintMaker with the callee view.
85 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing.
86 | * All constraints previously installed for the view will be removed.
87 | *
88 | * @param block scope within which you can build up the constraints which you wish to apply to the view.
89 | *
90 | * @return Array of created/updated MASConstraints
91 | */
92 | - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;
93 |
94 | @end
95 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/View+MASAdditions.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+MASAdditions.m
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 20/07/13.
6 | // Copyright (c) 2013 cloudling. All rights reserved.
7 | //
8 |
9 | #import "View+MASAdditions.h"
10 | #import
11 |
12 | @implementation MAS_VIEW (MASAdditions)
13 |
14 | - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
15 | self.translatesAutoresizingMaskIntoConstraints = NO;
16 | MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
17 | block(constraintMaker);
18 | return [constraintMaker install];
19 | }
20 |
21 | - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *))block {
22 | self.translatesAutoresizingMaskIntoConstraints = NO;
23 | MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
24 | constraintMaker.updateExisting = YES;
25 | block(constraintMaker);
26 | return [constraintMaker install];
27 | }
28 |
29 | - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block {
30 | self.translatesAutoresizingMaskIntoConstraints = NO;
31 | MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
32 | constraintMaker.removeExisting = YES;
33 | block(constraintMaker);
34 | return [constraintMaker install];
35 | }
36 |
37 | #pragma mark - NSLayoutAttribute properties
38 |
39 | - (MASViewAttribute *)mas_left {
40 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeft];
41 | }
42 |
43 | - (MASViewAttribute *)mas_top {
44 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTop];
45 | }
46 |
47 | - (MASViewAttribute *)mas_right {
48 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRight];
49 | }
50 |
51 | - (MASViewAttribute *)mas_bottom {
52 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottom];
53 | }
54 |
55 | - (MASViewAttribute *)mas_leading {
56 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeading];
57 | }
58 |
59 | - (MASViewAttribute *)mas_trailing {
60 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailing];
61 | }
62 |
63 | - (MASViewAttribute *)mas_width {
64 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeWidth];
65 | }
66 |
67 | - (MASViewAttribute *)mas_height {
68 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeHeight];
69 | }
70 |
71 | - (MASViewAttribute *)mas_centerX {
72 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterX];
73 | }
74 |
75 | - (MASViewAttribute *)mas_centerY {
76 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterY];
77 | }
78 |
79 | - (MASViewAttribute *)mas_baseline {
80 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBaseline];
81 | }
82 |
83 | - (MASViewAttribute *(^)(NSLayoutAttribute))mas_attribute
84 | {
85 | return ^(NSLayoutAttribute attr) {
86 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:attr];
87 | };
88 | }
89 |
90 | #if TARGET_OS_IPHONE
91 |
92 | - (MASViewAttribute *)mas_leftMargin {
93 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeftMargin];
94 | }
95 |
96 | - (MASViewAttribute *)mas_rightMargin {
97 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRightMargin];
98 | }
99 |
100 | - (MASViewAttribute *)mas_topMargin {
101 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTopMargin];
102 | }
103 |
104 | - (MASViewAttribute *)mas_bottomMargin {
105 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottomMargin];
106 | }
107 |
108 | - (MASViewAttribute *)mas_leadingMargin {
109 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeadingMargin];
110 | }
111 |
112 | - (MASViewAttribute *)mas_trailingMargin {
113 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailingMargin];
114 | }
115 |
116 | - (MASViewAttribute *)mas_centerXWithinMargins {
117 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterXWithinMargins];
118 | }
119 |
120 | - (MASViewAttribute *)mas_centerYWithinMargins {
121 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterYWithinMargins];
122 | }
123 |
124 | #endif
125 |
126 | #pragma mark - associated properties
127 |
128 | - (id)mas_key {
129 | return objc_getAssociatedObject(self, @selector(mas_key));
130 | }
131 |
132 | - (void)setMas_key:(id)key {
133 | objc_setAssociatedObject(self, @selector(mas_key), key, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
134 | }
135 |
136 | #pragma mark - heirachy
137 |
138 | - (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view {
139 | MAS_VIEW *closestCommonSuperview = nil;
140 |
141 | MAS_VIEW *secondViewSuperview = view;
142 | while (!closestCommonSuperview && secondViewSuperview) {
143 | MAS_VIEW *firstViewSuperview = self;
144 | while (!closestCommonSuperview && firstViewSuperview) {
145 | if (secondViewSuperview == firstViewSuperview) {
146 | closestCommonSuperview = secondViewSuperview;
147 | }
148 | firstViewSuperview = firstViewSuperview.superview;
149 | }
150 | secondViewSuperview = secondViewSuperview.superview;
151 | }
152 | return closestCommonSuperview;
153 | }
154 |
155 | @end
156 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/View+MASShorthandAdditions.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+MASShorthandAdditions.h
3 | // Masonry
4 | //
5 | // Created by Jonas Budelmann on 22/07/13.
6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved.
7 | //
8 |
9 | #import "View+MASAdditions.h"
10 |
11 | #ifdef MAS_SHORTHAND
12 |
13 | /**
14 | * Shorthand view additions without the 'mas_' prefixes,
15 | * only enabled if MAS_SHORTHAND is defined
16 | */
17 | @interface MAS_VIEW (MASShorthandAdditions)
18 |
19 | @property (nonatomic, strong, readonly) MASViewAttribute *left;
20 | @property (nonatomic, strong, readonly) MASViewAttribute *top;
21 | @property (nonatomic, strong, readonly) MASViewAttribute *right;
22 | @property (nonatomic, strong, readonly) MASViewAttribute *bottom;
23 | @property (nonatomic, strong, readonly) MASViewAttribute *leading;
24 | @property (nonatomic, strong, readonly) MASViewAttribute *trailing;
25 | @property (nonatomic, strong, readonly) MASViewAttribute *width;
26 | @property (nonatomic, strong, readonly) MASViewAttribute *height;
27 | @property (nonatomic, strong, readonly) MASViewAttribute *centerX;
28 | @property (nonatomic, strong, readonly) MASViewAttribute *centerY;
29 | @property (nonatomic, strong, readonly) MASViewAttribute *baseline;
30 | @property (nonatomic, strong, readonly) MASViewAttribute *(^attribute)(NSLayoutAttribute attr);
31 |
32 | #if TARGET_OS_IPHONE
33 |
34 | @property (nonatomic, strong, readonly) MASViewAttribute *leftMargin;
35 | @property (nonatomic, strong, readonly) MASViewAttribute *rightMargin;
36 | @property (nonatomic, strong, readonly) MASViewAttribute *topMargin;
37 | @property (nonatomic, strong, readonly) MASViewAttribute *bottomMargin;
38 | @property (nonatomic, strong, readonly) MASViewAttribute *leadingMargin;
39 | @property (nonatomic, strong, readonly) MASViewAttribute *trailingMargin;
40 | @property (nonatomic, strong, readonly) MASViewAttribute *centerXWithinMargins;
41 | @property (nonatomic, strong, readonly) MASViewAttribute *centerYWithinMargins;
42 |
43 | #endif
44 |
45 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block;
46 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block;
47 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block;
48 |
49 | @end
50 |
51 | #define MAS_ATTR_FORWARD(attr) \
52 | - (MASViewAttribute *)attr { \
53 | return [self mas_##attr]; \
54 | }
55 |
56 | @implementation MAS_VIEW (MASShorthandAdditions)
57 |
58 | MAS_ATTR_FORWARD(top);
59 | MAS_ATTR_FORWARD(left);
60 | MAS_ATTR_FORWARD(bottom);
61 | MAS_ATTR_FORWARD(right);
62 | MAS_ATTR_FORWARD(leading);
63 | MAS_ATTR_FORWARD(trailing);
64 | MAS_ATTR_FORWARD(width);
65 | MAS_ATTR_FORWARD(height);
66 | MAS_ATTR_FORWARD(centerX);
67 | MAS_ATTR_FORWARD(centerY);
68 | MAS_ATTR_FORWARD(baseline);
69 |
70 | #if TARGET_OS_IPHONE
71 |
72 | MAS_ATTR_FORWARD(leftMargin);
73 | MAS_ATTR_FORWARD(rightMargin);
74 | MAS_ATTR_FORWARD(topMargin);
75 | MAS_ATTR_FORWARD(bottomMargin);
76 | MAS_ATTR_FORWARD(leadingMargin);
77 | MAS_ATTR_FORWARD(trailingMargin);
78 | MAS_ATTR_FORWARD(centerXWithinMargins);
79 | MAS_ATTR_FORWARD(centerYWithinMargins);
80 |
81 | #endif
82 |
83 | - (MASViewAttribute *(^)(NSLayoutAttribute))attribute {
84 | return [self mas_attribute];
85 | }
86 |
87 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block {
88 | return [self mas_makeConstraints:block];
89 | }
90 |
91 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block {
92 | return [self mas_updateConstraints:block];
93 | }
94 |
95 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block {
96 | return [self mas_remakeConstraints:block];
97 | }
98 |
99 | @end
100 |
101 | #endif
102 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/ViewController+MASAdditions.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+MASAdditions.h
3 | // Masonry
4 | //
5 | // Created by Craig Siemens on 2015-06-23.
6 | //
7 | //
8 |
9 | #import "MASUtilities.h"
10 | #import "MASConstraintMaker.h"
11 | #import "MASViewAttribute.h"
12 |
13 | #ifdef MAS_VIEW_CONTROLLER
14 |
15 | @interface MAS_VIEW_CONTROLLER (MASAdditions)
16 |
17 | /**
18 | * following properties return a new MASViewAttribute with appropriate UILayoutGuide and NSLayoutAttribute
19 | */
20 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuide;
21 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuide;
22 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideTop;
23 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideBottom;
24 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideTop;
25 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideBottom;
26 |
27 |
28 | @end
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/Masonry/ViewController+MASAdditions.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+MASAdditions.m
3 | // Masonry
4 | //
5 | // Created by Craig Siemens on 2015-06-23.
6 | //
7 | //
8 |
9 | #import "ViewController+MASAdditions.h"
10 |
11 | #ifdef MAS_VIEW_CONTROLLER
12 |
13 | @implementation MAS_VIEW_CONTROLLER (MASAdditions)
14 |
15 | - (MASViewAttribute *)mas_topLayoutGuide {
16 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
17 | }
18 | - (MASViewAttribute *)mas_topLayoutGuideTop {
19 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeTop];
20 | }
21 | - (MASViewAttribute *)mas_topLayoutGuideBottom {
22 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
23 | }
24 |
25 | - (MASViewAttribute *)mas_bottomLayoutGuide {
26 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop];
27 | }
28 | - (MASViewAttribute *)mas_bottomLayoutGuideTop {
29 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop];
30 | }
31 | - (MASViewAttribute *)mas_bottomLayoutGuideBottom {
32 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
33 | }
34 |
35 |
36 |
37 | @end
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // SkfSwiftCammer
4 | //
5 | // Created by Kevin Sun on 16/4/13.
6 | // Copyright © 2016年 Kevin Sun. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // SkfSwiftCammer
4 | //
5 | // Created by Kevin Sun on 16/4/13.
6 | // Copyright © 2016年 Kevin Sun. All rights reserved.
7 | //
8 | #import
9 | #import "ViewController.h"
10 | /* 1. 在oc中使用swift文件
11 | 2. 创建全局编译文件 PrefixHeader.pch
12 | 3. 在全局预编译文件PrefixHeader.pch中 #import ‘项目名-Swift.h")
13 | 4. 现在就可以在oc中使用swift了
14 | 是不是很神奇
15 | 先导入ALCameraViewController到你的工程 然后在预编译文件里面添加#import ‘项目名-Swift.h" 就可以使用了
16 | */
17 | @interface ViewController ()
18 | @property (weak, nonatomic) IBOutlet UIButton *ssss;
19 | - (IBAction)kkkkk:(id)sender;
20 | @property (weak, nonatomic) IBOutlet UIImageView *Kimage;
21 | - (IBAction)KLibrary:(id)sender;
22 | - (IBAction)KCropping:(id)sender;
23 | @property(nonatomic,assign)BOOL IsOpneLibrary;
24 | @property(nonatomic,assign)BOOL IsOpneCropping;
25 | @property (weak, nonatomic) IBOutlet UISwitch *KLibarySwtich;
26 | @property (weak, nonatomic) IBOutlet UILabel *KlibrayLabel;
27 | @property (weak, nonatomic) IBOutlet UIButton *KCamera;
28 | @property (weak, nonatomic) IBOutlet UISwitch *KCroppingSwitch;
29 | @property (weak, nonatomic) IBOutlet UILabel *KCroppingLabel;
30 |
31 |
32 | @end
33 |
34 | @implementation ViewController
35 |
36 | - (void)viewDidLoad {
37 | [super viewDidLoad];
38 | //默认不打开从相册选择照片和裁剪功能
39 | self.IsOpneLibrary=NO;
40 | self.IsOpneCropping=NO;
41 | [self Addmasonry];
42 | }
43 | #pragma mark 添加约束 原谅我不会Autolayout
44 | -(void)Addmasonry{
45 | [self.KCamera mas_makeConstraints:^(MASConstraintMaker *make) {
46 | make.centerX.mas_equalTo(self.view.mas_centerX);
47 | make.centerY.mas_equalTo(self.view.mas_centerY);
48 | make.size.mas_equalTo(CGSizeMake(34, 17));
49 | }];
50 | [self.KLibarySwtich mas_makeConstraints:^(MASConstraintMaker *make) {
51 | make.centerY.mas_equalTo(self.KCamera.mas_centerY);
52 | make.right.mas_equalTo(self.KCamera.mas_left).offset(-70);
53 | }];
54 | [self.KCroppingSwitch mas_makeConstraints:^(MASConstraintMaker *make) {
55 | make.centerY.mas_equalTo(self.KCamera.mas_centerY);
56 | make.left.mas_equalTo(self.KCamera.mas_right).offset(70);
57 | }];
58 | [self.KlibrayLabel mas_makeConstraints:^(MASConstraintMaker *make) {
59 | make.centerX.mas_equalTo(self.KLibarySwtich.mas_centerX);
60 | make.size.mas_equalTo(CGSizeMake(68, 17));
61 | make.top.mas_equalTo(self.KCroppingSwitch.mas_bottom).offset(15);
62 |
63 | }];
64 | [self.KCroppingLabel mas_makeConstraints:^(MASConstraintMaker *make) {
65 | make.centerX.mas_equalTo(self.KCroppingSwitch.mas_centerX);
66 | make.size.mas_equalTo(CGSizeMake(68, 17));
67 | make.top.mas_equalTo(self.KCroppingSwitch.mas_bottom).offset(15);
68 | }];
69 |
70 |
71 | }
72 | - (void)didReceiveMemoryWarning {
73 | [super didReceiveMemoryWarning];
74 | // Dispose of any resources that can be recreated.
75 | }
76 |
77 | - (IBAction)kkkkk:(id)sender {
78 | ALCameraViewController *kk=[[ALCameraViewController alloc]initWithCroppingEnabled:self.IsOpneCropping allowsLibraryAccess:self.IsOpneLibrary completion:^(UIImage * sss, PHAsset * kkk) {
79 | self.Kimage.image=sss;
80 | [self dismissViewControllerAnimated:YES completion:nil];
81 |
82 | }];
83 |
84 |
85 |
86 |
87 | [self presentViewController:kk animated:YES completion:nil];
88 | }
89 | - (IBAction)KLibrary:(id)sender {
90 | UISwitch *switchButton = (UISwitch*)sender;
91 | BOOL isButtonOn = [switchButton isOn];
92 | if (isButtonOn) {
93 | NSLog(@"我点击了switch,设置self.IsOpneLibrary= YES");
94 | NSLog(@"self.IsOpneLibrary %d",self.IsOpneLibrary);
95 | self.IsOpneLibrary= YES;
96 | }else {
97 | self.IsOpneLibrary= NO;
98 | NSLog(@"self.IsOpneLibrary %d",self.IsOpneLibrary);
99 |
100 | }
101 | }
102 |
103 | - (IBAction)KCropping:(id)sender {
104 | UISwitch *switchButton = (UISwitch*)sender;
105 | BOOL isButtonOn = [switchButton isOn];
106 | if (isButtonOn) {
107 | NSLog(@"我点击了switch,设置self.IsOpneCropping= YES");
108 | NSLog(@"self.IsOpneLibrary %d",self.IsOpneCropping);
109 | self.IsOpneCropping= YES;
110 | }else {
111 | self.IsOpneCropping= NO;
112 | NSLog(@"self.IsOpneLibrary %d",self.IsOpneCropping);
113 |
114 | }
115 |
116 | }
117 | @end
118 |
--------------------------------------------------------------------------------
/SkfSwiftCammer/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // SkfSwiftCammer
4 | //
5 | // Created by Kevin Sun on 16/4/13.
6 | // Copyright © 2016年 Kevin Sun. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/SkfSwiftCammerTests/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 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/SkfSwiftCammerTests/SkfSwiftCammerTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SkfSwiftCammerTests.m
3 | // SkfSwiftCammerTests
4 | //
5 | // Created by Kevin Sun on 16/4/13.
6 | // Copyright © 2016年 Kevin Sun. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SkfSwiftCammerTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation SkfSwiftCammerTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/SkfSwiftCammerUITests/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 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/SkfSwiftCammerUITests/SkfSwiftCammerUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SkfSwiftCammerUITests.m
3 | // SkfSwiftCammerUITests
4 | //
5 | // Created by Kevin Sun on 16/4/13.
6 | // Copyright © 2016年 Kevin Sun. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SkfSwiftCammerUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation SkfSwiftCammerUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------