diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273.xcodeproj/project.pbxproj" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273.xcodeproj/project.pbxproj" index 4ed1e74..f1a4991 100644 --- "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273.xcodeproj/project.pbxproj" +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273.xcodeproj/project.pbxproj" @@ -8,7 +8,22 @@ /* Begin PBXBuildFile section */ 047099C81D00405A0066978B /* YTNavController.m in Sources */ = {isa = PBXBuildFile; fileRef = 047099C71D00405A0066978B /* YTNavController.m */; }; - 047099CF1D004BA40066978B /* YTSearchController.m in Sources */ = {isa = PBXBuildFile; fileRef = 047099CE1D004BA40066978B /* YTSearchController.m */; }; + 048F7E7F1D01ADF100DF692E /* UIBarButtonItem+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7E7E1D01ADF100DF692E /* UIBarButtonItem+Extension.m */; }; + 048F7E9B1D01CF2500DF692E /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 048F7E811D01CF2500DF692E /* Info.plist */; }; + 048F7E9C1D01CF2500DF692E /* MASCompositeConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7E831D01CF2500DF692E /* MASCompositeConstraint.m */; }; + 048F7E9D1D01CF2500DF692E /* MASConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7E861D01CF2500DF692E /* MASConstraint.m */; }; + 048F7E9E1D01CF2500DF692E /* MASConstraintMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7E881D01CF2500DF692E /* MASConstraintMaker.m */; }; + 048F7E9F1D01CF2500DF692E /* MASLayoutConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7E8A1D01CF2500DF692E /* MASLayoutConstraint.m */; }; + 048F7EA01D01CF2500DF692E /* MASViewAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7E8E1D01CF2500DF692E /* MASViewAttribute.m */; }; + 048F7EA11D01CF2500DF692E /* MASViewConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7E901D01CF2500DF692E /* MASViewConstraint.m */; }; + 048F7EA21D01CF2500DF692E /* NSArray+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7E921D01CF2500DF692E /* NSArray+MASAdditions.m */; }; + 048F7EA31D01CF2500DF692E /* NSLayoutConstraint+MASDebugAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7E951D01CF2500DF692E /* NSLayoutConstraint+MASDebugAdditions.m */; }; + 048F7EA41D01CF2500DF692E /* View+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7E971D01CF2500DF692E /* View+MASAdditions.m */; }; + 048F7EA51D01CF2500DF692E /* ViewController+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7E9A1D01CF2500DF692E /* ViewController+MASAdditions.m */; }; + 048F7EB01D01CFA000DF692E /* YTSearchController.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7EA91D01CFA000DF692E /* YTSearchController.m */; }; + 048F7EB11D01CFA000DF692E /* YTSearchViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7EAB1D01CFA000DF692E /* YTSearchViewController.m */; }; + 048F7EB21D01CFA000DF692E /* YTSearchBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7EAF1D01CFA000DF692E /* YTSearchBar.m */; }; + 048F7EB51D01D1CA00DF692E /* YTSearchFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 048F7EB41D01D1CA00DF692E /* YTSearchFooter.m */; }; 04BEB9C81CFFF4ED00C272FC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BEB9C71CFFF4ED00C272FC /* main.m */; }; 04BEB9D11CFFF4ED00C272FC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 04BEB9CF1CFFF4ED00C272FC /* Main.storyboard */; }; 04BEB9D31CFFF4ED00C272FC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 04BEB9D21CFFF4ED00C272FC /* Assets.xcassets */; }; @@ -42,8 +57,43 @@ /* Begin PBXFileReference section */ 047099C61D00405A0066978B /* YTNavController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTNavController.h; sourceTree = ""; }; 047099C71D00405A0066978B /* YTNavController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTNavController.m; sourceTree = ""; }; - 047099CD1D004BA40066978B /* YTSearchController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTSearchController.h; sourceTree = ""; }; - 047099CE1D004BA40066978B /* YTSearchController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTSearchController.m; sourceTree = ""; }; + 048F7E7B1D01A7CB00DF692E /* PrefixHeader.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; + 048F7E7D1D01ADF100DF692E /* UIBarButtonItem+Extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIBarButtonItem+Extension.h"; sourceTree = ""; }; + 048F7E7E1D01ADF100DF692E /* UIBarButtonItem+Extension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBarButtonItem+Extension.m"; sourceTree = ""; }; + 048F7E811D01CF2500DF692E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 048F7E821D01CF2500DF692E /* MASCompositeConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASCompositeConstraint.h; sourceTree = ""; }; + 048F7E831D01CF2500DF692E /* MASCompositeConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASCompositeConstraint.m; sourceTree = ""; }; + 048F7E841D01CF2500DF692E /* MASConstraint+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MASConstraint+Private.h"; sourceTree = ""; }; + 048F7E851D01CF2500DF692E /* MASConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASConstraint.h; sourceTree = ""; }; + 048F7E861D01CF2500DF692E /* MASConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASConstraint.m; sourceTree = ""; }; + 048F7E871D01CF2500DF692E /* MASConstraintMaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASConstraintMaker.h; sourceTree = ""; }; + 048F7E881D01CF2500DF692E /* MASConstraintMaker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASConstraintMaker.m; sourceTree = ""; }; + 048F7E891D01CF2500DF692E /* MASLayoutConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASLayoutConstraint.h; sourceTree = ""; }; + 048F7E8A1D01CF2500DF692E /* MASLayoutConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASLayoutConstraint.m; sourceTree = ""; }; + 048F7E8B1D01CF2500DF692E /* Masonry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Masonry.h; sourceTree = ""; }; + 048F7E8C1D01CF2500DF692E /* MASUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASUtilities.h; sourceTree = ""; }; + 048F7E8D1D01CF2500DF692E /* MASViewAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASViewAttribute.h; sourceTree = ""; }; + 048F7E8E1D01CF2500DF692E /* MASViewAttribute.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASViewAttribute.m; sourceTree = ""; }; + 048F7E8F1D01CF2500DF692E /* MASViewConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASViewConstraint.h; sourceTree = ""; }; + 048F7E901D01CF2500DF692E /* MASViewConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASViewConstraint.m; sourceTree = ""; }; + 048F7E911D01CF2500DF692E /* NSArray+MASAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MASAdditions.h"; sourceTree = ""; }; + 048F7E921D01CF2500DF692E /* NSArray+MASAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+MASAdditions.m"; sourceTree = ""; }; + 048F7E931D01CF2500DF692E /* NSArray+MASShorthandAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MASShorthandAdditions.h"; sourceTree = ""; }; + 048F7E941D01CF2500DF692E /* NSLayoutConstraint+MASDebugAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSLayoutConstraint+MASDebugAdditions.h"; sourceTree = ""; }; + 048F7E951D01CF2500DF692E /* NSLayoutConstraint+MASDebugAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSLayoutConstraint+MASDebugAdditions.m"; sourceTree = ""; }; + 048F7E961D01CF2500DF692E /* View+MASAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "View+MASAdditions.h"; sourceTree = ""; }; + 048F7E971D01CF2500DF692E /* View+MASAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "View+MASAdditions.m"; sourceTree = ""; }; + 048F7E981D01CF2500DF692E /* View+MASShorthandAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "View+MASShorthandAdditions.h"; sourceTree = ""; }; + 048F7E991D01CF2500DF692E /* ViewController+MASAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ViewController+MASAdditions.h"; sourceTree = ""; }; + 048F7E9A1D01CF2500DF692E /* ViewController+MASAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ViewController+MASAdditions.m"; sourceTree = ""; }; + 048F7EA81D01CFA000DF692E /* YTSearchController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTSearchController.h; sourceTree = ""; }; + 048F7EA91D01CFA000DF692E /* YTSearchController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTSearchController.m; sourceTree = ""; }; + 048F7EAA1D01CFA000DF692E /* YTSearchViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTSearchViewController.h; sourceTree = ""; }; + 048F7EAB1D01CFA000DF692E /* YTSearchViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTSearchViewController.m; sourceTree = ""; }; + 048F7EAE1D01CFA000DF692E /* YTSearchBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTSearchBar.h; sourceTree = ""; }; + 048F7EAF1D01CFA000DF692E /* YTSearchBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTSearchBar.m; sourceTree = ""; }; + 048F7EB31D01D1CA00DF692E /* YTSearchFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTSearchFooter.h; sourceTree = ""; }; + 048F7EB41D01D1CA00DF692E /* YTSearchFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTSearchFooter.m; sourceTree = ""; }; 04BEB9C31CFFF4EC00C272FC /* 仿搜狗阅读.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "仿搜狗阅读.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 04BEB9C71CFFF4ED00C272FC /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 04BEB9D01CFFF4ED00C272FC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; @@ -93,36 +143,83 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 047099C91D004B820066978B /* Search */ = { + 048F7E7C1D01AD9C00DF692E /* Category */ = { isa = PBXGroup; children = ( - 047099CA1D004B820066978B /* Controller */, - 047099CB1D004B820066978B /* Model */, - 047099CC1D004B820066978B /* View */, + 048F7E7D1D01ADF100DF692E /* UIBarButtonItem+Extension.h */, + 048F7E7E1D01ADF100DF692E /* UIBarButtonItem+Extension.m */, ); - name = Search; - path = Lib/Search; + path = Category; sourceTree = ""; }; - 047099CA1D004B820066978B /* Controller */ = { + 048F7E801D01CF2500DF692E /* Masonry */ = { isa = PBXGroup; children = ( - 047099CD1D004BA40066978B /* YTSearchController.h */, - 047099CE1D004BA40066978B /* YTSearchController.m */, + 048F7E811D01CF2500DF692E /* Info.plist */, + 048F7E821D01CF2500DF692E /* MASCompositeConstraint.h */, + 048F7E831D01CF2500DF692E /* MASCompositeConstraint.m */, + 048F7E841D01CF2500DF692E /* MASConstraint+Private.h */, + 048F7E851D01CF2500DF692E /* MASConstraint.h */, + 048F7E861D01CF2500DF692E /* MASConstraint.m */, + 048F7E871D01CF2500DF692E /* MASConstraintMaker.h */, + 048F7E881D01CF2500DF692E /* MASConstraintMaker.m */, + 048F7E891D01CF2500DF692E /* MASLayoutConstraint.h */, + 048F7E8A1D01CF2500DF692E /* MASLayoutConstraint.m */, + 048F7E8B1D01CF2500DF692E /* Masonry.h */, + 048F7E8C1D01CF2500DF692E /* MASUtilities.h */, + 048F7E8D1D01CF2500DF692E /* MASViewAttribute.h */, + 048F7E8E1D01CF2500DF692E /* MASViewAttribute.m */, + 048F7E8F1D01CF2500DF692E /* MASViewConstraint.h */, + 048F7E901D01CF2500DF692E /* MASViewConstraint.m */, + 048F7E911D01CF2500DF692E /* NSArray+MASAdditions.h */, + 048F7E921D01CF2500DF692E /* NSArray+MASAdditions.m */, + 048F7E931D01CF2500DF692E /* NSArray+MASShorthandAdditions.h */, + 048F7E941D01CF2500DF692E /* NSLayoutConstraint+MASDebugAdditions.h */, + 048F7E951D01CF2500DF692E /* NSLayoutConstraint+MASDebugAdditions.m */, + 048F7E961D01CF2500DF692E /* View+MASAdditions.h */, + 048F7E971D01CF2500DF692E /* View+MASAdditions.m */, + 048F7E981D01CF2500DF692E /* View+MASShorthandAdditions.h */, + 048F7E991D01CF2500DF692E /* ViewController+MASAdditions.h */, + 048F7E9A1D01CF2500DF692E /* ViewController+MASAdditions.m */, + ); + path = Masonry; + sourceTree = ""; + }; + 048F7EA61D01CFA000DF692E /* Search */ = { + isa = PBXGroup; + children = ( + 048F7EA71D01CFA000DF692E /* Controller */, + 048F7EAC1D01CFA000DF692E /* Model */, + 048F7EAD1D01CFA000DF692E /* View */, + ); + path = Search; + sourceTree = ""; + }; + 048F7EA71D01CFA000DF692E /* Controller */ = { + isa = PBXGroup; + children = ( + 048F7EA81D01CFA000DF692E /* YTSearchController.h */, + 048F7EA91D01CFA000DF692E /* YTSearchController.m */, + 048F7EAA1D01CFA000DF692E /* YTSearchViewController.h */, + 048F7EAB1D01CFA000DF692E /* YTSearchViewController.m */, ); path = Controller; sourceTree = ""; }; - 047099CB1D004B820066978B /* Model */ = { + 048F7EAC1D01CFA000DF692E /* Model */ = { isa = PBXGroup; children = ( ); path = Model; sourceTree = ""; }; - 047099CC1D004B820066978B /* View */ = { + 048F7EAD1D01CFA000DF692E /* View */ = { isa = PBXGroup; children = ( + 048F7EAE1D01CFA000DF692E /* YTSearchBar.h */, + 048F7EAF1D01CFA000DF692E /* YTSearchBar.m */, + 048F7EB31D01D1CA00DF692E /* YTSearchFooter.h */, + 048F7EB41D01D1CA00DF692E /* YTSearchFooter.m */, ); path = View; sourceTree = ""; @@ -189,7 +286,7 @@ 04BEB9F91CFFF8FA00C272FC /* Classes */ = { isa = PBXGroup; children = ( - 047099C91D004B820066978B /* Search */, + 048F7EA61D01CFA000DF692E /* Search */, 04C823351D00027E0020A25B /* Bookshelf */, 04C823311D00027A0020A25B /* Bookstore */, 04C8232D1D0002730020A25B /* Discover */, @@ -204,6 +301,7 @@ 04BEB9FE1CFFF8FA00C272FC /* Lib */ = { isa = PBXGroup; children = ( + 048F7E801D01CF2500DF692E /* Masonry */, ); path = Lib; sourceTree = ""; @@ -222,8 +320,10 @@ 04BEBA001CFFF8FA00C272FC /* Others */ = { isa = PBXGroup; children = ( + 048F7E7C1D01AD9C00DF692E /* Category */, 04BEBA011CFFF8FA00C272FC /* AppDelegate.h */, 04BEBA021CFFF8FA00C272FC /* AppDelegate.m */, + 048F7E7B1D01A7CB00DF692E /* PrefixHeader.pch */, ); path = Others; sourceTree = ""; @@ -439,6 +539,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 048F7E9B1D01CF2500DF692E /* Info.plist in Resources */, 04BEB9D61CFFF4ED00C272FC /* LaunchScreen.storyboard in Resources */, 04BEB9D31CFFF4ED00C272FC /* Assets.xcassets in Resources */, 04BEB9D11CFFF4ED00C272FC /* Main.storyboard in Resources */, @@ -467,13 +568,27 @@ buildActionMask = 2147483647; files = ( 04C8233B1D0002A60020A25B /* BookshelfViewController.m in Sources */, + 048F7EB51D01D1CA00DF692E /* YTSearchFooter.m in Sources */, 04BEBA0C1CFFF8FA00C272FC /* AppDelegate.m in Sources */, + 048F7EB21D01CFA000DF692E /* YTSearchBar.m in Sources */, 047099C81D00405A0066978B /* YTNavController.m in Sources */, + 048F7E9C1D01CF2500DF692E /* MASCompositeConstraint.m in Sources */, + 048F7EA11D01CF2500DF692E /* MASViewConstraint.m in Sources */, + 048F7EB01D01CFA000DF692E /* YTSearchController.m in Sources */, 04C8233E1D00040A0020A25B /* YTBookstoreViewController.m in Sources */, + 048F7EA41D01CF2500DF692E /* View+MASAdditions.m in Sources */, + 048F7EA31D01CF2500DF692E /* NSLayoutConstraint+MASDebugAdditions.m in Sources */, + 048F7E9F1D01CF2500DF692E /* MASLayoutConstraint.m in Sources */, + 048F7EA51D01CF2500DF692E /* ViewController+MASAdditions.m in Sources */, + 048F7E9E1D01CF2500DF692E /* MASConstraintMaker.m in Sources */, + 048F7E7F1D01ADF100DF692E /* UIBarButtonItem+Extension.m in Sources */, + 048F7EB11D01CFA000DF692E /* YTSearchViewController.m in Sources */, 04BEBA0F1CFFF94400C272FC /* YTTabBarController.m in Sources */, 04C823411D00045B0020A25B /* YTDiscoverViewController.m in Sources */, - 047099CF1D004BA40066978B /* YTSearchController.m in Sources */, + 048F7EA21D01CF2500DF692E /* NSArray+MASAdditions.m in Sources */, + 048F7EA01D01CF2500DF692E /* MASViewAttribute.m in Sources */, 04BEB9C81CFFF4ED00C272FC /* main.m in Sources */, + 048F7E9D1D01CF2500DF692E /* MASConstraint.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -555,6 +670,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -598,6 +714,7 @@ ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -618,6 +735,8 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "仿搜狗阅读/Classes/Others/PrefixHeader.pch"; INFOPLIST_FILE = "仿搜狗阅读/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -633,6 +752,8 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "仿搜狗阅读/Classes/Others/PrefixHeader.pch"; INFOPLIST_FILE = "仿搜狗阅读/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273.xcodeproj/project.xcworkspace/xcuserdata/Mac.xcuserdatad/UserInterfaceState.xcuserstate" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273.xcodeproj/project.xcworkspace/xcuserdata/Mac.xcuserdatad/UserInterfaceState.xcuserstate" index a8e2ec6..7919fb3 100644 Binary files "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273.xcodeproj/project.xcworkspace/xcuserdata/Mac.xcuserdatad/UserInterfaceState.xcuserstate" and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273.xcodeproj/project.xcworkspace/xcuserdata/Mac.xcuserdatad/UserInterfaceState.xcuserstate" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/Contents.json" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/Contents.json" new file mode 100644 index 0000000..0c3dea0 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "addBookIcon-1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "addBookIcon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "addBookIcon@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/addBookIcon-1.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/addBookIcon-1.png" new file mode 100644 index 0000000..5e06d3c Binary files /dev/null and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/addBookIcon-1.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/addBookIcon@2x.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/addBookIcon@2x.png" new file mode 100644 index 0000000..428103f Binary files /dev/null and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/addBookIcon@2x.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/addBookIcon@3x.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/addBookIcon@3x.png" new file mode 100644 index 0000000..cda9ec6 Binary files /dev/null and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/addBookIcon.imageset/addBookIcon@3x.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/Contents.json" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/Contents.json" new file mode 100644 index 0000000..0d0fcdf --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "bookShelfSearchBtn-1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "bookShelfSearchBtn@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "bookShelfSearchBtn@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/bookShelfSearchBtn-1.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/bookShelfSearchBtn-1.png" new file mode 100644 index 0000000..8529ca1 Binary files /dev/null and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/bookShelfSearchBtn-1.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/bookShelfSearchBtn@2x.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/bookShelfSearchBtn@2x.png" new file mode 100644 index 0000000..71caa7f Binary files /dev/null and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/bookShelfSearchBtn@2x.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/bookShelfSearchBtn@3x.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/bookShelfSearchBtn@3x.png" new file mode 100644 index 0000000..132337d Binary files /dev/null and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/bookShelfSearchBtn.imageset/bookShelfSearchBtn@3x.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon-1.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon-1.png" index 8d4b5b5..9a58cff 100644 Binary files "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon-1.png" and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon-1.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon@2x.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon@2x.png" index a607a3b..8e58c39 100644 Binary files "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon@2x.png" and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon@2x.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon@3x-1.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon@3x-1.png" index 66b2b59..9ed69db 100644 Binary files "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon@3x-1.png" and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuoicon.imageset/search_sousuoicon@3x-1.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/Contents.json" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/Contents.json" new file mode 100644 index 0000000..b13f9db --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "search_sousuokuang-1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "search_sousuokuang@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "search_sousuokuang@3x-1.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/search_sousuokuang-1.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/search_sousuokuang-1.png" new file mode 100644 index 0000000..0f2fd4d Binary files /dev/null and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/search_sousuokuang-1.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/search_sousuokuang@2x.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/search_sousuokuang@2x.png" new file mode 100644 index 0000000..2ea746e Binary files /dev/null and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/search_sousuokuang@2x.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/search_sousuokuang@3x-1.png" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/search_sousuokuang@3x-1.png" new file mode 100644 index 0000000..124c108 Binary files /dev/null and "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Assets.xcassets/search_sousuokuang.imageset/search_sousuokuang@3x-1.png" differ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Base.lproj/Main.storyboard" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Base.lproj/Main.storyboard" index 78ec685..5d90251 100644 --- "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Base.lproj/Main.storyboard" +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Base.lproj/Main.storyboard" @@ -3,6 +3,7 @@ + @@ -44,7 +45,7 @@ - + @@ -73,7 +74,21 @@ - + + + + + + + + + + + + + + + @@ -119,13 +134,14 @@ - + - + + @@ -135,38 +151,34 @@ - - + + - - - - - - - + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + - - + + - + @@ -200,7 +212,14 @@ - + + + + + + + + @@ -209,12 +228,13 @@ + + - diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Bookshelf/Controller/BookshelfViewController.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Bookshelf/Controller/BookshelfViewController.m" index 20a40b4..523dfdc 100644 --- "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Bookshelf/Controller/BookshelfViewController.m" +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Bookshelf/Controller/BookshelfViewController.m" @@ -7,8 +7,10 @@ // #import "BookshelfViewController.h" - +#import "YTSearchController.h" @interface BookshelfViewController () +- (IBAction)searchBtnClick:(id)sender; + @end @@ -90,4 +92,16 @@ - (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)act } */ +- (IBAction)searchBtnClick:(id)sender { + CATransition* transition = [CATransition animation]; + transition.duration = 0.5; + transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade + transition.subtype = kCATransitionFromTop; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom + [self.navigationController.view.layer addAnimation:transition forKey:nil]; + + YTSearchController *searchVC = [[self storyboard]instantiateViewControllerWithIdentifier:@"searchVC"]; + + [[self navigationController]pushViewController:searchVC animated:NO]; +} @end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Bookstore/Controller/YTBookstoreViewController.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Bookstore/Controller/YTBookstoreViewController.m" index ca5646c..0e9302c 100644 --- "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Bookstore/Controller/YTBookstoreViewController.m" +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Bookstore/Controller/YTBookstoreViewController.m" @@ -7,9 +7,11 @@ // #import "YTBookstoreViewController.h" - +#import "YTSearchController.h" @interface YTBookstoreViewController () +- (IBAction)searchBtnClick:(id)sender; + @end @implementation YTBookstoreViewController @@ -35,4 +37,17 @@ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { } */ +- (IBAction)searchBtnClick:(id)sender { + CATransition* transition = [CATransition animation]; + transition.duration = 0.5; + transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade + transition.subtype = kCATransitionFromTop; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom + [self.navigationController.view.layer addAnimation:transition forKey:nil]; + + YTSearchController *searchVC = [[self storyboard]instantiateViewControllerWithIdentifier:@"searchVC"]; + + [[self navigationController]pushViewController:searchVC animated:NO]; + +} @end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Discover/Controller/YTDiscoverViewController.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Discover/Controller/YTDiscoverViewController.m" index f5258b2..1140004 100644 --- "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Discover/Controller/YTDiscoverViewController.m" +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Discover/Controller/YTDiscoverViewController.m" @@ -7,10 +7,13 @@ // #import "YTDiscoverViewController.h" - +#import "YTSearchController.h" +#import "YTSearchViewController.h" @interface YTDiscoverViewController () @property (weak, nonatomic) IBOutlet UIWebView *discoverWebView; +- (IBAction)searchBtnClick:(id)sender; + @end @implementation YTDiscoverViewController @@ -18,7 +21,8 @@ @implementation YTDiscoverViewController - (void)viewDidLoad { [super viewDidLoad]; self.discoverWebView.scrollView.bounces = NO; - + + //加载网络地址 // self.discoverWebView.delegate = self; NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://k.sogou.com/abs/ios/v3/find"]]; @@ -27,19 +31,23 @@ - (void)viewDidLoad { } -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} -/* -#pragma mark - Navigation -// In a storyboard-based application, you will often want to do a little preparation before navigation -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - // Get the new view controller using [segue destinationViewController]. - // Pass the selected object to the new view controller. -} -*/ + + +- (IBAction)searchBtnClick:(id)sender { + CATransition* transition = [CATransition animation]; + transition.duration = 0.5; + transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade + transition.subtype = kCATransitionFromTop; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom + [self.navigationController.view.layer addAnimation:transition forKey:nil]; + + YTSearchViewController *searchVC = [[self storyboard]instantiateViewControllerWithIdentifier:@"searchVC"]; + + + + [[self navigationController]pushViewController:searchVC animated:NO]; +} @end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/Info.plist" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/Info.plist" new file mode 100755 index 0000000..d3de8ee --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/Info.plist" @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASCompositeConstraint.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASCompositeConstraint.h" new file mode 100755 index 0000000..934c6f1 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASCompositeConstraint.h" @@ -0,0 +1,26 @@ +// +// MASCompositeConstraint.h +// Masonry +// +// Created by Jonas Budelmann on 21/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import "MASConstraint.h" +#import "MASUtilities.h" + +/** + * A group of MASConstraint objects + */ +@interface MASCompositeConstraint : MASConstraint + +/** + * Creates a composite with a predefined array of children + * + * @param children child MASConstraints + * + * @return a composite constraint + */ +- (id)initWithChildren:(NSArray *)children; + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASCompositeConstraint.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASCompositeConstraint.m" new file mode 100755 index 0000000..ed63ed6 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASCompositeConstraint.m" @@ -0,0 +1,177 @@ +// +// MASCompositeConstraint.m +// Masonry +// +// Created by Jonas Budelmann on 21/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import "MASCompositeConstraint.h" +#import "MASConstraint+Private.h" + +@interface MASCompositeConstraint () + +@property (nonatomic, strong) id mas_key; +@property (nonatomic, strong) NSMutableArray *childConstraints; + +@end + +@implementation MASCompositeConstraint + +- (id)initWithChildren:(NSArray *)children { + self = [super init]; + if (!self) return nil; + + _childConstraints = [children mutableCopy]; + for (MASConstraint *constraint in _childConstraints) { + constraint.delegate = self; + } + + return self; +} + +#pragma mark - MASConstraintDelegate + +- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint { + NSUInteger index = [self.childConstraints indexOfObject:constraint]; + NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint); + [self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint]; +} + +- (MASConstraint *)constraint:(MASConstraint __unused *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { + id strongDelegate = self.delegate; + MASConstraint *newConstraint = [strongDelegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; + newConstraint.delegate = self; + [self.childConstraints addObject:newConstraint]; + return newConstraint; +} + +#pragma mark - NSLayoutConstraint multiplier proxies + +- (MASConstraint * (^)(CGFloat))multipliedBy { + return ^id(CGFloat multiplier) { + for (MASConstraint *constraint in self.childConstraints) { + constraint.multipliedBy(multiplier); + } + return self; + }; +} + +- (MASConstraint * (^)(CGFloat))dividedBy { + return ^id(CGFloat divider) { + for (MASConstraint *constraint in self.childConstraints) { + constraint.dividedBy(divider); + } + return self; + }; +} + +#pragma mark - MASLayoutPriority proxy + +- (MASConstraint * (^)(MASLayoutPriority))priority { + return ^id(MASLayoutPriority priority) { + for (MASConstraint *constraint in self.childConstraints) { + constraint.priority(priority); + } + return self; + }; +} + +#pragma mark - NSLayoutRelation proxy + +- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { + return ^id(id attr, NSLayoutRelation relation) { + for (MASConstraint *constraint in self.childConstraints.copy) { + constraint.equalToWithRelation(attr, relation); + } + return self; + }; +} + +#pragma mark - attribute chaining + +- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { + [self constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; + return self; +} + +#pragma mark - Animator proxy + +#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) + +- (MASConstraint *)animator { + for (MASConstraint *constraint in self.childConstraints) { + [constraint animator]; + } + return self; +} + +#endif + +#pragma mark - debug helpers + +- (MASConstraint * (^)(id))key { + return ^id(id key) { + self.mas_key = key; + int i = 0; + for (MASConstraint *constraint in self.childConstraints) { + constraint.key([NSString stringWithFormat:@"%@[%d]", key, i++]); + } + return self; + }; +} + +#pragma mark - NSLayoutConstraint constant setters + +- (void)setInsets:(MASEdgeInsets)insets { + for (MASConstraint *constraint in self.childConstraints) { + constraint.insets = insets; + } +} + +- (void)setOffset:(CGFloat)offset { + for (MASConstraint *constraint in self.childConstraints) { + constraint.offset = offset; + } +} + +- (void)setSizeOffset:(CGSize)sizeOffset { + for (MASConstraint *constraint in self.childConstraints) { + constraint.sizeOffset = sizeOffset; + } +} + +- (void)setCenterOffset:(CGPoint)centerOffset { + for (MASConstraint *constraint in self.childConstraints) { + constraint.centerOffset = centerOffset; + } +} + +#pragma mark - MASConstraint + +- (void)activate { + for (MASConstraint *constraint in self.childConstraints) { + [constraint activate]; + } +} + +- (void)deactivate { + for (MASConstraint *constraint in self.childConstraints) { + [constraint deactivate]; + } +} + +- (void)install { + for (MASConstraint *constraint in self.childConstraints) { + constraint.updateExisting = self.updateExisting; + [constraint install]; + } +} + +- (void)uninstall { + for (MASConstraint *constraint in self.childConstraints) { + [constraint uninstall]; + } +} + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraint+Private.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraint+Private.h" new file mode 100755 index 0000000..ee0fd96 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraint+Private.h" @@ -0,0 +1,66 @@ +// +// MASConstraint+Private.h +// Masonry +// +// Created by Nick Tymchenko on 29/04/14. +// Copyright (c) 2014 cloudling. All rights reserved. +// + +#import "MASConstraint.h" + +@protocol MASConstraintDelegate; + + +@interface MASConstraint () + +/** + * Whether or not to check for an existing constraint instead of adding constraint + */ +@property (nonatomic, assign) BOOL updateExisting; + +/** + * Usually MASConstraintMaker but could be a parent MASConstraint + */ +@property (nonatomic, weak) id delegate; + +/** + * Based on a provided value type, is equal to calling: + * NSNumber - setOffset: + * NSValue with CGPoint - setPointOffset: + * NSValue with CGSize - setSizeOffset: + * NSValue with MASEdgeInsets - setInsets: + */ +- (void)setLayoutConstantWithValue:(NSValue *)value; + +@end + + +@interface MASConstraint (Abstract) + +/** + * Sets the constraint relation to given NSLayoutRelation + * returns a block which accepts one of the following: + * MASViewAttribute, UIView, NSValue, NSArray + * see readme for more details. + */ +- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation; + +/** + * Override to set a custom chaining behaviour + */ +- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; + +@end + + +@protocol MASConstraintDelegate + +/** + * Notifies the delegate when the constraint needs to be replaced with another constraint. For example + * A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks + */ +- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint; + +- (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraint.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraint.h" new file mode 100755 index 0000000..70a10c8 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraint.h" @@ -0,0 +1,258 @@ +// +// MASConstraint.h +// Masonry +// +// Created by Jonas Budelmann on 22/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import "MASUtilities.h" + +/** + * Enables Constraints to be created with chainable syntax + * Constraint can represent single NSLayoutConstraint (MASViewConstraint) + * or a group of NSLayoutConstraints (MASComposisteConstraint) + */ +@interface MASConstraint : NSObject + +// Chaining Support + +/** + * Modifies the NSLayoutConstraint constant, + * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following + * NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight + */ +- (MASConstraint * (^)(MASEdgeInsets insets))insets; + +/** + * Modifies the NSLayoutConstraint constant, + * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following + * NSLayoutAttributeWidth, NSLayoutAttributeHeight + */ +- (MASConstraint * (^)(CGSize offset))sizeOffset; + +/** + * Modifies the NSLayoutConstraint constant, + * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following + * NSLayoutAttributeCenterX, NSLayoutAttributeCenterY + */ +- (MASConstraint * (^)(CGPoint offset))centerOffset; + +/** + * Modifies the NSLayoutConstraint constant + */ +- (MASConstraint * (^)(CGFloat offset))offset; + +/** + * Modifies the NSLayoutConstraint constant based on a value type + */ +- (MASConstraint * (^)(NSValue *value))valueOffset; + +/** + * Sets the NSLayoutConstraint multiplier property + */ +- (MASConstraint * (^)(CGFloat multiplier))multipliedBy; + +/** + * Sets the NSLayoutConstraint multiplier to 1.0/dividedBy + */ +- (MASConstraint * (^)(CGFloat divider))dividedBy; + +/** + * Sets the NSLayoutConstraint priority to a float or MASLayoutPriority + */ +- (MASConstraint * (^)(MASLayoutPriority priority))priority; + +/** + * Sets the NSLayoutConstraint priority to MASLayoutPriorityLow + */ +- (MASConstraint * (^)())priorityLow; + +/** + * Sets the NSLayoutConstraint priority to MASLayoutPriorityMedium + */ +- (MASConstraint * (^)())priorityMedium; + +/** + * Sets the NSLayoutConstraint priority to MASLayoutPriorityHigh + */ +- (MASConstraint * (^)())priorityHigh; + +/** + * Sets the constraint relation to NSLayoutRelationEqual + * returns a block which accepts one of the following: + * MASViewAttribute, UIView, NSValue, NSArray + * see readme for more details. + */ +- (MASConstraint * (^)(id attr))equalTo; + +/** + * Sets the constraint relation to NSLayoutRelationGreaterThanOrEqual + * returns a block which accepts one of the following: + * MASViewAttribute, UIView, NSValue, NSArray + * see readme for more details. + */ +- (MASConstraint * (^)(id attr))greaterThanOrEqualTo; + +/** + * Sets the constraint relation to NSLayoutRelationLessThanOrEqual + * returns a block which accepts one of the following: + * MASViewAttribute, UIView, NSValue, NSArray + * see readme for more details. + */ +- (MASConstraint * (^)(id attr))lessThanOrEqualTo; + +/** + * Optional semantic property which has no effect but improves the readability of constraint + */ +- (MASConstraint *)with; + +/** + * Optional semantic property which has no effect but improves the readability of constraint + */ +- (MASConstraint *)and; + +/** + * Creates a new MASCompositeConstraint with the called attribute and reciever + */ +- (MASConstraint *)left; +- (MASConstraint *)top; +- (MASConstraint *)right; +- (MASConstraint *)bottom; +- (MASConstraint *)leading; +- (MASConstraint *)trailing; +- (MASConstraint *)width; +- (MASConstraint *)height; +- (MASConstraint *)centerX; +- (MASConstraint *)centerY; +- (MASConstraint *)baseline; + +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + +- (MASConstraint *)firstBaseline; +- (MASConstraint *)lastBaseline; + +#endif + +#if TARGET_OS_IPHONE || TARGET_OS_TV + +- (MASConstraint *)leftMargin; +- (MASConstraint *)rightMargin; +- (MASConstraint *)topMargin; +- (MASConstraint *)bottomMargin; +- (MASConstraint *)leadingMargin; +- (MASConstraint *)trailingMargin; +- (MASConstraint *)centerXWithinMargins; +- (MASConstraint *)centerYWithinMargins; + +#endif + + +/** + * Sets the constraint debug name + */ +- (MASConstraint * (^)(id key))key; + +// NSLayoutConstraint constant Setters +// for use outside of mas_updateConstraints/mas_makeConstraints blocks + +/** + * Modifies the NSLayoutConstraint constant, + * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following + * NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight + */ +- (void)setInsets:(MASEdgeInsets)insets; + +/** + * Modifies the NSLayoutConstraint constant, + * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following + * NSLayoutAttributeWidth, NSLayoutAttributeHeight + */ +- (void)setSizeOffset:(CGSize)sizeOffset; + +/** + * Modifies the NSLayoutConstraint constant, + * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following + * NSLayoutAttributeCenterX, NSLayoutAttributeCenterY + */ +- (void)setCenterOffset:(CGPoint)centerOffset; + +/** + * Modifies the NSLayoutConstraint constant + */ +- (void)setOffset:(CGFloat)offset; + + +// NSLayoutConstraint Installation support + +#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) +/** + * Whether or not to go through the animator proxy when modifying the constraint + */ +@property (nonatomic, copy, readonly) MASConstraint *animator; +#endif + +/** + * Activates an NSLayoutConstraint if it's supported by an OS. + * Invokes install otherwise. + */ +- (void)activate; + +/** + * Deactivates previously installed/activated NSLayoutConstraint. + */ +- (void)deactivate; + +/** + * Creates a NSLayoutConstraint and adds it to the appropriate view. + */ +- (void)install; + +/** + * Removes previously installed NSLayoutConstraint + */ +- (void)uninstall; + +@end + + +/** + * Convenience auto-boxing macros for MASConstraint methods. + * + * Defining MAS_SHORTHAND_GLOBALS will turn on auto-boxing for default syntax. + * A potential drawback of this is that the unprefixed macros will appear in global scope. + */ +#define mas_equalTo(...) equalTo(MASBoxValue((__VA_ARGS__))) +#define mas_greaterThanOrEqualTo(...) greaterThanOrEqualTo(MASBoxValue((__VA_ARGS__))) +#define mas_lessThanOrEqualTo(...) lessThanOrEqualTo(MASBoxValue((__VA_ARGS__))) + +#define mas_offset(...) valueOffset(MASBoxValue((__VA_ARGS__))) + + +#ifdef MAS_SHORTHAND_GLOBALS + +#define equalTo(...) mas_equalTo(__VA_ARGS__) +#define greaterThanOrEqualTo(...) mas_greaterThanOrEqualTo(__VA_ARGS__) +#define lessThanOrEqualTo(...) mas_lessThanOrEqualTo(__VA_ARGS__) + +#define offset(...) mas_offset(__VA_ARGS__) + +#endif + + +@interface MASConstraint (AutoboxingSupport) + +/** + * Aliases to corresponding relation methods (for shorthand macros) + * Also needed to aid autocompletion + */ +- (MASConstraint * (^)(id attr))mas_equalTo; +- (MASConstraint * (^)(id attr))mas_greaterThanOrEqualTo; +- (MASConstraint * (^)(id attr))mas_lessThanOrEqualTo; + +/** + * A dummy method to aid autocompletion + */ +- (MASConstraint * (^)(id offset))mas_offset; + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraint.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraint.m" new file mode 100755 index 0000000..f24ec10 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraint.m" @@ -0,0 +1,292 @@ +// +// MASConstraint.m +// Masonry +// +// Created by Nick Tymchenko on 1/20/14. +// + +#import "MASConstraint.h" +#import "MASConstraint+Private.h" + +#define MASMethodNotImplemented() \ + @throw [NSException exceptionWithName:NSInternalInconsistencyException \ + reason:[NSString stringWithFormat:@"You must override %@ in a subclass.", NSStringFromSelector(_cmd)] \ + userInfo:nil] + +@implementation MASConstraint + +#pragma mark - Init + +- (id)init { + NSAssert(![self isMemberOfClass:[MASConstraint class]], @"MASConstraint is an abstract class, you should not instantiate it directly."); + return [super init]; +} + +#pragma mark - NSLayoutRelation proxies + +- (MASConstraint * (^)(id))equalTo { + return ^id(id attribute) { + return self.equalToWithRelation(attribute, NSLayoutRelationEqual); + }; +} + +- (MASConstraint * (^)(id))mas_equalTo { + return ^id(id attribute) { + return self.equalToWithRelation(attribute, NSLayoutRelationEqual); + }; +} + +- (MASConstraint * (^)(id))greaterThanOrEqualTo { + return ^id(id attribute) { + return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual); + }; +} + +- (MASConstraint * (^)(id))mas_greaterThanOrEqualTo { + return ^id(id attribute) { + return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual); + }; +} + +- (MASConstraint * (^)(id))lessThanOrEqualTo { + return ^id(id attribute) { + return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual); + }; +} + +- (MASConstraint * (^)(id))mas_lessThanOrEqualTo { + return ^id(id attribute) { + return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual); + }; +} + +#pragma mark - MASLayoutPriority proxies + +- (MASConstraint * (^)())priorityLow { + return ^id{ + self.priority(MASLayoutPriorityDefaultLow); + return self; + }; +} + +- (MASConstraint * (^)())priorityMedium { + return ^id{ + self.priority(MASLayoutPriorityDefaultMedium); + return self; + }; +} + +- (MASConstraint * (^)())priorityHigh { + return ^id{ + self.priority(MASLayoutPriorityDefaultHigh); + return self; + }; +} + +#pragma mark - NSLayoutConstraint constant proxies + +- (MASConstraint * (^)(MASEdgeInsets))insets { + return ^id(MASEdgeInsets insets){ + self.insets = insets; + return self; + }; +} + +- (MASConstraint * (^)(CGSize))sizeOffset { + return ^id(CGSize offset) { + self.sizeOffset = offset; + return self; + }; +} + +- (MASConstraint * (^)(CGPoint))centerOffset { + return ^id(CGPoint offset) { + self.centerOffset = offset; + return self; + }; +} + +- (MASConstraint * (^)(CGFloat))offset { + return ^id(CGFloat offset){ + self.offset = offset; + return self; + }; +} + +- (MASConstraint * (^)(NSValue *value))valueOffset { + return ^id(NSValue *offset) { + NSAssert([offset isKindOfClass:NSValue.class], @"expected an NSValue offset, got: %@", offset); + [self setLayoutConstantWithValue:offset]; + return self; + }; +} + +- (MASConstraint * (^)(id offset))mas_offset { + // Will never be called due to macro + return nil; +} + +#pragma mark - NSLayoutConstraint constant setter + +- (void)setLayoutConstantWithValue:(NSValue *)value { + if ([value isKindOfClass:NSNumber.class]) { + self.offset = [(NSNumber *)value doubleValue]; + } else if (strcmp(value.objCType, @encode(CGPoint)) == 0) { + CGPoint point; + [value getValue:&point]; + self.centerOffset = point; + } else if (strcmp(value.objCType, @encode(CGSize)) == 0) { + CGSize size; + [value getValue:&size]; + self.sizeOffset = size; + } else if (strcmp(value.objCType, @encode(MASEdgeInsets)) == 0) { + MASEdgeInsets insets; + [value getValue:&insets]; + self.insets = insets; + } else { + NSAssert(NO, @"attempting to set layout constant with unsupported value: %@", value); + } +} + +#pragma mark - Semantic properties + +- (MASConstraint *)with { + return self; +} + +- (MASConstraint *)and { + return self; +} + +#pragma mark - Chaining + +- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute __unused)layoutAttribute { + MASMethodNotImplemented(); +} + +- (MASConstraint *)left { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft]; +} + +- (MASConstraint *)top { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop]; +} + +- (MASConstraint *)right { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight]; +} + +- (MASConstraint *)bottom { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom]; +} + +- (MASConstraint *)leading { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading]; +} + +- (MASConstraint *)trailing { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing]; +} + +- (MASConstraint *)width { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth]; +} + +- (MASConstraint *)height { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight]; +} + +- (MASConstraint *)centerX { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX]; +} + +- (MASConstraint *)centerY { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY]; +} + +- (MASConstraint *)baseline { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline]; +} + +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + +- (MASConstraint *)firstBaseline { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeFirstBaseline]; +} +- (MASConstraint *)lastBaseline { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLastBaseline]; +} + +#endif + +#if TARGET_OS_IPHONE || TARGET_OS_TV + +- (MASConstraint *)leftMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin]; +} + +- (MASConstraint *)rightMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin]; +} + +- (MASConstraint *)topMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin]; +} + +- (MASConstraint *)bottomMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin]; +} + +- (MASConstraint *)leadingMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin]; +} + +- (MASConstraint *)trailingMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin]; +} + +- (MASConstraint *)centerXWithinMargins { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins]; +} + +- (MASConstraint *)centerYWithinMargins { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins]; +} + +#endif + +#pragma mark - Abstract + +- (MASConstraint * (^)(CGFloat multiplier))multipliedBy { MASMethodNotImplemented(); } + +- (MASConstraint * (^)(CGFloat divider))dividedBy { MASMethodNotImplemented(); } + +- (MASConstraint * (^)(MASLayoutPriority priority))priority { MASMethodNotImplemented(); } + +- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { MASMethodNotImplemented(); } + +- (MASConstraint * (^)(id key))key { MASMethodNotImplemented(); } + +- (void)setInsets:(MASEdgeInsets __unused)insets { MASMethodNotImplemented(); } + +- (void)setSizeOffset:(CGSize __unused)sizeOffset { MASMethodNotImplemented(); } + +- (void)setCenterOffset:(CGPoint __unused)centerOffset { MASMethodNotImplemented(); } + +- (void)setOffset:(CGFloat __unused)offset { MASMethodNotImplemented(); } + +#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) + +- (MASConstraint *)animator { MASMethodNotImplemented(); } + +#endif + +- (void)activate { MASMethodNotImplemented(); } + +- (void)deactivate { MASMethodNotImplemented(); } + +- (void)install { MASMethodNotImplemented(); } + +- (void)uninstall { MASMethodNotImplemented(); } + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraintMaker.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraintMaker.h" new file mode 100755 index 0000000..8f72b4c --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraintMaker.h" @@ -0,0 +1,146 @@ +// +// MASConstraintBuilder.h +// Masonry +// +// Created by Jonas Budelmann on 20/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import "MASConstraint.h" +#import "MASUtilities.h" + +typedef NS_OPTIONS(NSInteger, MASAttribute) { + MASAttributeLeft = 1 << NSLayoutAttributeLeft, + MASAttributeRight = 1 << NSLayoutAttributeRight, + MASAttributeTop = 1 << NSLayoutAttributeTop, + MASAttributeBottom = 1 << NSLayoutAttributeBottom, + MASAttributeLeading = 1 << NSLayoutAttributeLeading, + MASAttributeTrailing = 1 << NSLayoutAttributeTrailing, + MASAttributeWidth = 1 << NSLayoutAttributeWidth, + MASAttributeHeight = 1 << NSLayoutAttributeHeight, + MASAttributeCenterX = 1 << NSLayoutAttributeCenterX, + MASAttributeCenterY = 1 << NSLayoutAttributeCenterY, + MASAttributeBaseline = 1 << NSLayoutAttributeBaseline, + +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + + MASAttributeFirstBaseline = 1 << NSLayoutAttributeFirstBaseline, + MASAttributeLastBaseline = 1 << NSLayoutAttributeLastBaseline, + +#endif + +#if TARGET_OS_IPHONE || TARGET_OS_TV + + MASAttributeLeftMargin = 1 << NSLayoutAttributeLeftMargin, + MASAttributeRightMargin = 1 << NSLayoutAttributeRightMargin, + MASAttributeTopMargin = 1 << NSLayoutAttributeTopMargin, + MASAttributeBottomMargin = 1 << NSLayoutAttributeBottomMargin, + MASAttributeLeadingMargin = 1 << NSLayoutAttributeLeadingMargin, + MASAttributeTrailingMargin = 1 << NSLayoutAttributeTrailingMargin, + MASAttributeCenterXWithinMargins = 1 << NSLayoutAttributeCenterXWithinMargins, + MASAttributeCenterYWithinMargins = 1 << NSLayoutAttributeCenterYWithinMargins, + +#endif + +}; + +/** + * Provides factory methods for creating MASConstraints. + * Constraints are collected until they are ready to be installed + * + */ +@interface MASConstraintMaker : NSObject + +/** + * The following properties return a new MASViewConstraint + * with the first item set to the makers associated view and the appropriate MASViewAttribute + */ +@property (nonatomic, strong, readonly) MASConstraint *left; +@property (nonatomic, strong, readonly) MASConstraint *top; +@property (nonatomic, strong, readonly) MASConstraint *right; +@property (nonatomic, strong, readonly) MASConstraint *bottom; +@property (nonatomic, strong, readonly) MASConstraint *leading; +@property (nonatomic, strong, readonly) MASConstraint *trailing; +@property (nonatomic, strong, readonly) MASConstraint *width; +@property (nonatomic, strong, readonly) MASConstraint *height; +@property (nonatomic, strong, readonly) MASConstraint *centerX; +@property (nonatomic, strong, readonly) MASConstraint *centerY; +@property (nonatomic, strong, readonly) MASConstraint *baseline; + +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + +@property (nonatomic, strong, readonly) MASConstraint *firstBaseline; +@property (nonatomic, strong, readonly) MASConstraint *lastBaseline; + +#endif + +#if TARGET_OS_IPHONE || TARGET_OS_TV + +@property (nonatomic, strong, readonly) MASConstraint *leftMargin; +@property (nonatomic, strong, readonly) MASConstraint *rightMargin; +@property (nonatomic, strong, readonly) MASConstraint *topMargin; +@property (nonatomic, strong, readonly) MASConstraint *bottomMargin; +@property (nonatomic, strong, readonly) MASConstraint *leadingMargin; +@property (nonatomic, strong, readonly) MASConstraint *trailingMargin; +@property (nonatomic, strong, readonly) MASConstraint *centerXWithinMargins; +@property (nonatomic, strong, readonly) MASConstraint *centerYWithinMargins; + +#endif + +/** + * Returns a block which creates a new MASCompositeConstraint with the first item set + * to the makers associated view and children corresponding to the set bits in the + * MASAttribute parameter. Combine multiple attributes via binary-or. + */ +@property (nonatomic, strong, readonly) MASConstraint *(^attributes)(MASAttribute attrs); + +/** + * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeEdges + * which generates the appropriate MASViewConstraint children (top, left, bottom, right) + * with the first item set to the makers associated view + */ +@property (nonatomic, strong, readonly) MASConstraint *edges; + +/** + * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeSize + * which generates the appropriate MASViewConstraint children (width, height) + * with the first item set to the makers associated view + */ +@property (nonatomic, strong, readonly) MASConstraint *size; + +/** + * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeCenter + * which generates the appropriate MASViewConstraint children (centerX, centerY) + * with the first item set to the makers associated view + */ +@property (nonatomic, strong, readonly) MASConstraint *center; + +/** + * Whether or not to check for an existing constraint instead of adding constraint + */ +@property (nonatomic, assign) BOOL updateExisting; + +/** + * Whether or not to remove existing constraints prior to installing + */ +@property (nonatomic, assign) BOOL removeExisting; + +/** + * initialises the maker with a default view + * + * @param view any MASConstrait are created with this view as the first item + * + * @return a new MASConstraintMaker + */ +- (id)initWithView:(MAS_VIEW *)view; + +/** + * Calls install method on any MASConstraints which have been created by this maker + * + * @return an array of all the installed MASConstraints + */ +- (NSArray *)install; + +- (MASConstraint * (^)(dispatch_block_t))group; + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraintMaker.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraintMaker.m" new file mode 100755 index 0000000..6e40a26 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASConstraintMaker.m" @@ -0,0 +1,273 @@ +// +// MASConstraintBuilder.m +// Masonry +// +// Created by Jonas Budelmann on 20/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import "MASConstraintMaker.h" +#import "MASViewConstraint.h" +#import "MASCompositeConstraint.h" +#import "MASConstraint+Private.h" +#import "MASViewAttribute.h" +#import "View+MASAdditions.h" + +@interface MASConstraintMaker () + +@property (nonatomic, weak) MAS_VIEW *view; +@property (nonatomic, strong) NSMutableArray *constraints; + +@end + +@implementation MASConstraintMaker + +- (id)initWithView:(MAS_VIEW *)view { + self = [super init]; + if (!self) return nil; + + self.view = view; + self.constraints = NSMutableArray.new; + + return self; +} + +- (NSArray *)install { + if (self.removeExisting) { + NSArray *installedConstraints = [MASViewConstraint installedConstraintsForView:self.view]; + for (MASConstraint *constraint in installedConstraints) { + [constraint uninstall]; + } + } + NSArray *constraints = self.constraints.copy; + for (MASConstraint *constraint in constraints) { + constraint.updateExisting = self.updateExisting; + [constraint install]; + } + [self.constraints removeAllObjects]; + return constraints; +} + +#pragma mark - MASConstraintDelegate + +- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint { + NSUInteger index = [self.constraints indexOfObject:constraint]; + NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint); + [self.constraints replaceObjectAtIndex:index withObject:replacementConstraint]; +} + +- (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { + MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute]; + MASViewConstraint *newConstraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute]; + if ([constraint isKindOfClass:MASViewConstraint.class]) { + //replace with composite constraint + NSArray *children = @[constraint, newConstraint]; + MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children]; + compositeConstraint.delegate = self; + [self constraint:constraint shouldBeReplacedWithConstraint:compositeConstraint]; + return compositeConstraint; + } + if (!constraint) { + newConstraint.delegate = self; + [self.constraints addObject:newConstraint]; + } + return newConstraint; +} + +- (MASConstraint *)addConstraintWithAttributes:(MASAttribute)attrs { + __unused MASAttribute anyAttribute = (MASAttributeLeft | MASAttributeRight | MASAttributeTop | MASAttributeBottom | MASAttributeLeading + | MASAttributeTrailing | MASAttributeWidth | MASAttributeHeight | MASAttributeCenterX + | MASAttributeCenterY | MASAttributeBaseline +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + | MASAttributeFirstBaseline | MASAttributeLastBaseline +#endif +#if TARGET_OS_IPHONE || TARGET_OS_TV + | MASAttributeLeftMargin | MASAttributeRightMargin | MASAttributeTopMargin | MASAttributeBottomMargin + | MASAttributeLeadingMargin | MASAttributeTrailingMargin | MASAttributeCenterXWithinMargins + | MASAttributeCenterYWithinMargins +#endif + ); + + NSAssert((attrs & anyAttribute) != 0, @"You didn't pass any attribute to make.attributes(...)"); + + NSMutableArray *attributes = [NSMutableArray array]; + + if (attrs & MASAttributeLeft) [attributes addObject:self.view.mas_left]; + if (attrs & MASAttributeRight) [attributes addObject:self.view.mas_right]; + if (attrs & MASAttributeTop) [attributes addObject:self.view.mas_top]; + if (attrs & MASAttributeBottom) [attributes addObject:self.view.mas_bottom]; + if (attrs & MASAttributeLeading) [attributes addObject:self.view.mas_leading]; + if (attrs & MASAttributeTrailing) [attributes addObject:self.view.mas_trailing]; + if (attrs & MASAttributeWidth) [attributes addObject:self.view.mas_width]; + if (attrs & MASAttributeHeight) [attributes addObject:self.view.mas_height]; + if (attrs & MASAttributeCenterX) [attributes addObject:self.view.mas_centerX]; + if (attrs & MASAttributeCenterY) [attributes addObject:self.view.mas_centerY]; + if (attrs & MASAttributeBaseline) [attributes addObject:self.view.mas_baseline]; + +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + + if (attrs & MASAttributeFirstBaseline) [attributes addObject:self.view.mas_firstBaseline]; + if (attrs & MASAttributeLastBaseline) [attributes addObject:self.view.mas_lastBaseline]; + +#endif + +#if TARGET_OS_IPHONE || TARGET_OS_TV + + if (attrs & MASAttributeLeftMargin) [attributes addObject:self.view.mas_leftMargin]; + if (attrs & MASAttributeRightMargin) [attributes addObject:self.view.mas_rightMargin]; + if (attrs & MASAttributeTopMargin) [attributes addObject:self.view.mas_topMargin]; + if (attrs & MASAttributeBottomMargin) [attributes addObject:self.view.mas_bottomMargin]; + if (attrs & MASAttributeLeadingMargin) [attributes addObject:self.view.mas_leadingMargin]; + if (attrs & MASAttributeTrailingMargin) [attributes addObject:self.view.mas_trailingMargin]; + if (attrs & MASAttributeCenterXWithinMargins) [attributes addObject:self.view.mas_centerXWithinMargins]; + if (attrs & MASAttributeCenterYWithinMargins) [attributes addObject:self.view.mas_centerYWithinMargins]; + +#endif + + NSMutableArray *children = [NSMutableArray arrayWithCapacity:attributes.count]; + + for (MASViewAttribute *a in attributes) { + [children addObject:[[MASViewConstraint alloc] initWithFirstViewAttribute:a]]; + } + + MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children]; + constraint.delegate = self; + [self.constraints addObject:constraint]; + return constraint; +} + +#pragma mark - standard Attributes + +- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { + return [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute]; +} + +- (MASConstraint *)left { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft]; +} + +- (MASConstraint *)top { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop]; +} + +- (MASConstraint *)right { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight]; +} + +- (MASConstraint *)bottom { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom]; +} + +- (MASConstraint *)leading { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading]; +} + +- (MASConstraint *)trailing { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing]; +} + +- (MASConstraint *)width { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth]; +} + +- (MASConstraint *)height { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight]; +} + +- (MASConstraint *)centerX { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX]; +} + +- (MASConstraint *)centerY { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY]; +} + +- (MASConstraint *)baseline { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline]; +} + +- (MASConstraint *(^)(MASAttribute))attributes { + return ^(MASAttribute attrs){ + return [self addConstraintWithAttributes:attrs]; + }; +} + +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + +- (MASConstraint *)firstBaseline { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeFirstBaseline]; +} + +- (MASConstraint *)lastBaseline { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLastBaseline]; +} + +#endif + + +#if TARGET_OS_IPHONE || TARGET_OS_TV + +- (MASConstraint *)leftMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin]; +} + +- (MASConstraint *)rightMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin]; +} + +- (MASConstraint *)topMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin]; +} + +- (MASConstraint *)bottomMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin]; +} + +- (MASConstraint *)leadingMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin]; +} + +- (MASConstraint *)trailingMargin { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin]; +} + +- (MASConstraint *)centerXWithinMargins { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins]; +} + +- (MASConstraint *)centerYWithinMargins { + return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins]; +} + +#endif + + +#pragma mark - composite Attributes + +- (MASConstraint *)edges { + return [self addConstraintWithAttributes:MASAttributeTop | MASAttributeLeft | MASAttributeRight | MASAttributeBottom]; +} + +- (MASConstraint *)size { + return [self addConstraintWithAttributes:MASAttributeWidth | MASAttributeHeight]; +} + +- (MASConstraint *)center { + return [self addConstraintWithAttributes:MASAttributeCenterX | MASAttributeCenterY]; +} + +#pragma mark - grouping + +- (MASConstraint *(^)(dispatch_block_t group))group { + return ^id(dispatch_block_t group) { + NSInteger previousCount = self.constraints.count; + group(); + + NSArray *children = [self.constraints subarrayWithRange:NSMakeRange(previousCount, self.constraints.count - previousCount)]; + MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children]; + constraint.delegate = self; + return constraint; + }; +} + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASLayoutConstraint.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASLayoutConstraint.h" new file mode 100755 index 0000000..699041c --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASLayoutConstraint.h" @@ -0,0 +1,22 @@ +// +// MASLayoutConstraint.h +// Masonry +// +// Created by Jonas Budelmann on 3/08/13. +// Copyright (c) 2013 Jonas Budelmann. All rights reserved. +// + +#import "MASUtilities.h" + +/** + * When you are debugging or printing the constraints attached to a view this subclass + * makes it easier to identify which constraints have been created via Masonry + */ +@interface MASLayoutConstraint : NSLayoutConstraint + +/** + * a key to associate with this constraint + */ +@property (nonatomic, strong) id mas_key; + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASLayoutConstraint.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASLayoutConstraint.m" new file mode 100755 index 0000000..3483f02 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASLayoutConstraint.m" @@ -0,0 +1,13 @@ +// +// MASLayoutConstraint.m +// Masonry +// +// Created by Jonas Budelmann on 3/08/13. +// Copyright (c) 2013 Jonas Budelmann. All rights reserved. +// + +#import "MASLayoutConstraint.h" + +@implementation MASLayoutConstraint + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASUtilities.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASUtilities.h" new file mode 100755 index 0000000..1dbfd93 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASUtilities.h" @@ -0,0 +1,136 @@ +// +// MASUtilities.h +// Masonry +// +// Created by Jonas Budelmann on 19/08/13. +// Copyright (c) 2013 Jonas Budelmann. All rights reserved. +// + +#import + + + +#if TARGET_OS_IPHONE || TARGET_OS_TV + + #import + #define MAS_VIEW UIView + #define MAS_VIEW_CONTROLLER UIViewController + #define MASEdgeInsets UIEdgeInsets + + typedef UILayoutPriority MASLayoutPriority; + static const MASLayoutPriority MASLayoutPriorityRequired = UILayoutPriorityRequired; + static const MASLayoutPriority MASLayoutPriorityDefaultHigh = UILayoutPriorityDefaultHigh; + static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 500; + static const MASLayoutPriority MASLayoutPriorityDefaultLow = UILayoutPriorityDefaultLow; + static const MASLayoutPriority MASLayoutPriorityFittingSizeLevel = UILayoutPriorityFittingSizeLevel; + +#elif TARGET_OS_MAC + + #import + #define MAS_VIEW NSView + #define MASEdgeInsets NSEdgeInsets + + typedef NSLayoutPriority MASLayoutPriority; + static const MASLayoutPriority MASLayoutPriorityRequired = NSLayoutPriorityRequired; + static const MASLayoutPriority MASLayoutPriorityDefaultHigh = NSLayoutPriorityDefaultHigh; + static const MASLayoutPriority MASLayoutPriorityDragThatCanResizeWindow = NSLayoutPriorityDragThatCanResizeWindow; + static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 501; + static const MASLayoutPriority MASLayoutPriorityWindowSizeStayPut = NSLayoutPriorityWindowSizeStayPut; + static const MASLayoutPriority MASLayoutPriorityDragThatCannotResizeWindow = NSLayoutPriorityDragThatCannotResizeWindow; + static const MASLayoutPriority MASLayoutPriorityDefaultLow = NSLayoutPriorityDefaultLow; + static const MASLayoutPriority MASLayoutPriorityFittingSizeCompression = NSLayoutPriorityFittingSizeCompression; + +#endif + +/** + * Allows you to attach keys to objects matching the variable names passed. + * + * view1.mas_key = @"view1", view2.mas_key = @"view2"; + * + * is equivalent to: + * + * MASAttachKeys(view1, view2); + */ +#define MASAttachKeys(...) \ + { \ + NSDictionary *keyPairs = NSDictionaryOfVariableBindings(__VA_ARGS__); \ + for (id key in keyPairs.allKeys) { \ + id obj = keyPairs[key]; \ + NSAssert([obj respondsToSelector:@selector(setMas_key:)], \ + @"Cannot attach mas_key to %@", obj); \ + [obj setMas_key:key]; \ + } \ + } + +/** + * Used to create object hashes + * Based on http://www.mikeash.com/pyblog/friday-qa-2010-06-18-implementing-equality-and-hashing.html + */ +#define MAS_NSUINT_BIT (CHAR_BIT * sizeof(NSUInteger)) +#define MAS_NSUINTROTATE(val, howmuch) ((((NSUInteger)val) << howmuch) | (((NSUInteger)val) >> (MAS_NSUINT_BIT - howmuch))) + +/** + * Given a scalar or struct value, wraps it in NSValue + * Based on EXPObjectify: https://github.com/specta/expecta + */ +static inline id _MASBoxValue(const char *type, ...) { + va_list v; + va_start(v, type); + id obj = nil; + if (strcmp(type, @encode(id)) == 0) { + id actual = va_arg(v, id); + obj = actual; + } else if (strcmp(type, @encode(CGPoint)) == 0) { + CGPoint actual = (CGPoint)va_arg(v, CGPoint); + obj = [NSValue value:&actual withObjCType:type]; + } else if (strcmp(type, @encode(CGSize)) == 0) { + CGSize actual = (CGSize)va_arg(v, CGSize); + obj = [NSValue value:&actual withObjCType:type]; + } else if (strcmp(type, @encode(MASEdgeInsets)) == 0) { + MASEdgeInsets actual = (MASEdgeInsets)va_arg(v, MASEdgeInsets); + obj = [NSValue value:&actual withObjCType:type]; + } else if (strcmp(type, @encode(double)) == 0) { + double actual = (double)va_arg(v, double); + obj = [NSNumber numberWithDouble:actual]; + } else if (strcmp(type, @encode(float)) == 0) { + float actual = (float)va_arg(v, double); + obj = [NSNumber numberWithFloat:actual]; + } else if (strcmp(type, @encode(int)) == 0) { + int actual = (int)va_arg(v, int); + obj = [NSNumber numberWithInt:actual]; + } else if (strcmp(type, @encode(long)) == 0) { + long actual = (long)va_arg(v, long); + obj = [NSNumber numberWithLong:actual]; + } else if (strcmp(type, @encode(long long)) == 0) { + long long actual = (long long)va_arg(v, long long); + obj = [NSNumber numberWithLongLong:actual]; + } else if (strcmp(type, @encode(short)) == 0) { + short actual = (short)va_arg(v, int); + obj = [NSNumber numberWithShort:actual]; + } else if (strcmp(type, @encode(char)) == 0) { + char actual = (char)va_arg(v, int); + obj = [NSNumber numberWithChar:actual]; + } else if (strcmp(type, @encode(bool)) == 0) { + bool actual = (bool)va_arg(v, int); + obj = [NSNumber numberWithBool:actual]; + } else if (strcmp(type, @encode(unsigned char)) == 0) { + unsigned char actual = (unsigned char)va_arg(v, unsigned int); + obj = [NSNumber numberWithUnsignedChar:actual]; + } else if (strcmp(type, @encode(unsigned int)) == 0) { + unsigned int actual = (unsigned int)va_arg(v, unsigned int); + obj = [NSNumber numberWithUnsignedInt:actual]; + } else if (strcmp(type, @encode(unsigned long)) == 0) { + unsigned long actual = (unsigned long)va_arg(v, unsigned long); + obj = [NSNumber numberWithUnsignedLong:actual]; + } else if (strcmp(type, @encode(unsigned long long)) == 0) { + unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long); + obj = [NSNumber numberWithUnsignedLongLong:actual]; + } else if (strcmp(type, @encode(unsigned short)) == 0) { + unsigned short actual = (unsigned short)va_arg(v, unsigned int); + obj = [NSNumber numberWithUnsignedShort:actual]; + } + va_end(v); + return obj; +} + +#define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value)) diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewAttribute.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewAttribute.h" new file mode 100755 index 0000000..f8eb700 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewAttribute.h" @@ -0,0 +1,49 @@ +// +// MASAttribute.h +// Masonry +// +// Created by Jonas Budelmann on 21/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import "MASUtilities.h" + +/** + * An immutable tuple which stores the view and the related NSLayoutAttribute. + * Describes part of either the left or right hand side of a constraint equation + */ +@interface MASViewAttribute : NSObject + +/** + * The view which the reciever relates to. Can be nil if item is not a view. + */ +@property (nonatomic, weak, readonly) MAS_VIEW *view; + +/** + * The item which the reciever relates to. + */ +@property (nonatomic, weak, readonly) id item; + +/** + * The attribute which the reciever relates to + */ +@property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute; + +/** + * Convenience initializer. + */ +- (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute; + +/** + * The designated initializer. + */ +- (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute; + +/** + * Determine whether the layoutAttribute is a size attribute + * + * @return YES if layoutAttribute is equal to NSLayoutAttributeWidth or NSLayoutAttributeHeight + */ +- (BOOL)isSizeAttribute; + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewAttribute.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewAttribute.m" new file mode 100755 index 0000000..7131025 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewAttribute.m" @@ -0,0 +1,46 @@ +// +// MASAttribute.m +// Masonry +// +// Created by Jonas Budelmann on 21/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import "MASViewAttribute.h" + +@implementation MASViewAttribute + +- (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute { + self = [self initWithView:view item:view layoutAttribute:layoutAttribute]; + return self; +} + +- (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute { + self = [super init]; + if (!self) return nil; + + _view = view; + _item = item; + _layoutAttribute = layoutAttribute; + + return self; +} + +- (BOOL)isSizeAttribute { + return self.layoutAttribute == NSLayoutAttributeWidth + || self.layoutAttribute == NSLayoutAttributeHeight; +} + +- (BOOL)isEqual:(MASViewAttribute *)viewAttribute { + if ([viewAttribute isKindOfClass:self.class]) { + return self.view == viewAttribute.view + && self.layoutAttribute == viewAttribute.layoutAttribute; + } + return [super isEqual:viewAttribute]; +} + +- (NSUInteger)hash { + return MAS_NSUINTROTATE([self.view hash], MAS_NSUINT_BIT / 2) ^ self.layoutAttribute; +} + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewConstraint.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewConstraint.h" new file mode 100755 index 0000000..5c78f7a --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewConstraint.h" @@ -0,0 +1,48 @@ +// +// MASConstraint.h +// Masonry +// +// Created by Jonas Budelmann on 20/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import "MASViewAttribute.h" +#import "MASConstraint.h" +#import "MASLayoutConstraint.h" +#import "MASUtilities.h" + +/** + * A single constraint. + * Contains the attributes neccessary for creating a NSLayoutConstraint and adding it to the appropriate view + */ +@interface MASViewConstraint : MASConstraint + +/** + * First item/view and first attribute of the NSLayoutConstraint + */ +@property (nonatomic, strong, readonly) MASViewAttribute *firstViewAttribute; + +/** + * Second item/view and second attribute of the NSLayoutConstraint + */ +@property (nonatomic, strong, readonly) MASViewAttribute *secondViewAttribute; + +/** + * initialises the MASViewConstraint with the first part of the equation + * + * @param firstViewAttribute view.mas_left, view.mas_width etc. + * + * @return a new view constraint + */ +- (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute; + +/** + * Returns all MASViewConstraints installed with this view as a first item. + * + * @param view A view to retrieve constraints for. + * + * @return An array of MASViewConstraints. + */ ++ (NSArray *)installedConstraintsForView:(MAS_VIEW *)view; + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewConstraint.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewConstraint.m" new file mode 100755 index 0000000..e8ccdcb --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/MASViewConstraint.m" @@ -0,0 +1,396 @@ +// +// MASConstraint.m +// Masonry +// +// Created by Jonas Budelmann on 20/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import "MASViewConstraint.h" +#import "MASConstraint+Private.h" +#import "MASCompositeConstraint.h" +#import "MASLayoutConstraint.h" +#import "View+MASAdditions.h" +#import + +@interface MAS_VIEW (MASConstraints) + +@property (nonatomic, readonly) NSMutableSet *mas_installedConstraints; + +@end + +@implementation MAS_VIEW (MASConstraints) + +static char kInstalledConstraintsKey; + +- (NSMutableSet *)mas_installedConstraints { + NSMutableSet *constraints = objc_getAssociatedObject(self, &kInstalledConstraintsKey); + if (!constraints) { + constraints = [NSMutableSet set]; + objc_setAssociatedObject(self, &kInstalledConstraintsKey, constraints, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return constraints; +} + +@end + + +@interface MASViewConstraint () + +@property (nonatomic, strong, readwrite) MASViewAttribute *secondViewAttribute; +@property (nonatomic, weak) MAS_VIEW *installedView; +@property (nonatomic, weak) MASLayoutConstraint *layoutConstraint; +@property (nonatomic, assign) NSLayoutRelation layoutRelation; +@property (nonatomic, assign) MASLayoutPriority layoutPriority; +@property (nonatomic, assign) CGFloat layoutMultiplier; +@property (nonatomic, assign) CGFloat layoutConstant; +@property (nonatomic, assign) BOOL hasLayoutRelation; +@property (nonatomic, strong) id mas_key; +@property (nonatomic, assign) BOOL useAnimator; + +@end + +@implementation MASViewConstraint + +- (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute { + self = [super init]; + if (!self) return nil; + + _firstViewAttribute = firstViewAttribute; + self.layoutPriority = MASLayoutPriorityRequired; + self.layoutMultiplier = 1; + + return self; +} + +#pragma mark - NSCoping + +- (id)copyWithZone:(NSZone __unused *)zone { + MASViewConstraint *constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:self.firstViewAttribute]; + constraint.layoutConstant = self.layoutConstant; + constraint.layoutRelation = self.layoutRelation; + constraint.layoutPriority = self.layoutPriority; + constraint.layoutMultiplier = self.layoutMultiplier; + constraint.delegate = self.delegate; + return constraint; +} + +#pragma mark - Public + ++ (NSArray *)installedConstraintsForView:(MAS_VIEW *)view { + return [view.mas_installedConstraints allObjects]; +} + +#pragma mark - Private + +- (void)setLayoutConstant:(CGFloat)layoutConstant { + _layoutConstant = layoutConstant; + +#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) + if (self.useAnimator) { + [self.layoutConstraint.animator setConstant:layoutConstant]; + } else { + self.layoutConstraint.constant = layoutConstant; + } +#else + self.layoutConstraint.constant = layoutConstant; +#endif +} + +- (void)setLayoutRelation:(NSLayoutRelation)layoutRelation { + _layoutRelation = layoutRelation; + self.hasLayoutRelation = YES; +} + +- (BOOL)supportsActiveProperty { + return [self.layoutConstraint respondsToSelector:@selector(isActive)]; +} + +- (BOOL)isActive { + BOOL active = YES; + if ([self supportsActiveProperty]) { + active = [self.layoutConstraint isActive]; + } + + return active; +} + +- (BOOL)hasBeenInstalled { + return (self.layoutConstraint != nil) && [self isActive]; +} + +- (void)setSecondViewAttribute:(id)secondViewAttribute { + if ([secondViewAttribute isKindOfClass:NSValue.class]) { + [self setLayoutConstantWithValue:secondViewAttribute]; + } else if ([secondViewAttribute isKindOfClass:MAS_VIEW.class]) { + _secondViewAttribute = [[MASViewAttribute alloc] initWithView:secondViewAttribute layoutAttribute:self.firstViewAttribute.layoutAttribute]; + } else if ([secondViewAttribute isKindOfClass:MASViewAttribute.class]) { + _secondViewAttribute = secondViewAttribute; + } else { + NSAssert(NO, @"attempting to add unsupported attribute: %@", secondViewAttribute); + } +} + +#pragma mark - NSLayoutConstraint multiplier proxies + +- (MASConstraint * (^)(CGFloat))multipliedBy { + return ^id(CGFloat multiplier) { + NSAssert(!self.hasBeenInstalled, + @"Cannot modify constraint multiplier after it has been installed"); + + self.layoutMultiplier = multiplier; + return self; + }; +} + + +- (MASConstraint * (^)(CGFloat))dividedBy { + return ^id(CGFloat divider) { + NSAssert(!self.hasBeenInstalled, + @"Cannot modify constraint multiplier after it has been installed"); + + self.layoutMultiplier = 1.0/divider; + return self; + }; +} + +#pragma mark - MASLayoutPriority proxy + +- (MASConstraint * (^)(MASLayoutPriority))priority { + return ^id(MASLayoutPriority priority) { + NSAssert(!self.hasBeenInstalled, + @"Cannot modify constraint priority after it has been installed"); + + self.layoutPriority = priority; + return self; + }; +} + +#pragma mark - NSLayoutRelation proxy + +- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { + return ^id(id attribute, NSLayoutRelation relation) { + if ([attribute isKindOfClass:NSArray.class]) { + NSAssert(!self.hasLayoutRelation, @"Redefinition of constraint relation"); + NSMutableArray *children = NSMutableArray.new; + for (id attr in attribute) { + MASViewConstraint *viewConstraint = [self copy]; + viewConstraint.secondViewAttribute = attr; + [children addObject:viewConstraint]; + } + MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children]; + compositeConstraint.delegate = self.delegate; + [self.delegate constraint:self shouldBeReplacedWithConstraint:compositeConstraint]; + return compositeConstraint; + } else { + NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSValue.class], @"Redefinition of constraint relation"); + self.layoutRelation = relation; + self.secondViewAttribute = attribute; + return self; + } + }; +} + +#pragma mark - Semantic properties + +- (MASConstraint *)with { + return self; +} + +- (MASConstraint *)and { + return self; +} + +#pragma mark - attribute chaining + +- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { + NSAssert(!self.hasLayoutRelation, @"Attributes should be chained before defining the constraint relation"); + + return [self.delegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; +} + +#pragma mark - Animator proxy + +#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) + +- (MASConstraint *)animator { + self.useAnimator = YES; + return self; +} + +#endif + +#pragma mark - debug helpers + +- (MASConstraint * (^)(id))key { + return ^id(id key) { + self.mas_key = key; + return self; + }; +} + +#pragma mark - NSLayoutConstraint constant setters + +- (void)setInsets:(MASEdgeInsets)insets { + NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute; + switch (layoutAttribute) { + case NSLayoutAttributeLeft: + case NSLayoutAttributeLeading: + self.layoutConstant = insets.left; + break; + case NSLayoutAttributeTop: + self.layoutConstant = insets.top; + break; + case NSLayoutAttributeBottom: + self.layoutConstant = -insets.bottom; + break; + case NSLayoutAttributeRight: + case NSLayoutAttributeTrailing: + self.layoutConstant = -insets.right; + break; + default: + break; + } +} + +- (void)setOffset:(CGFloat)offset { + self.layoutConstant = offset; +} + +- (void)setSizeOffset:(CGSize)sizeOffset { + NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute; + switch (layoutAttribute) { + case NSLayoutAttributeWidth: + self.layoutConstant = sizeOffset.width; + break; + case NSLayoutAttributeHeight: + self.layoutConstant = sizeOffset.height; + break; + default: + break; + } +} + +- (void)setCenterOffset:(CGPoint)centerOffset { + NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute; + switch (layoutAttribute) { + case NSLayoutAttributeCenterX: + self.layoutConstant = centerOffset.x; + break; + case NSLayoutAttributeCenterY: + self.layoutConstant = centerOffset.y; + break; + default: + break; + } +} + +#pragma mark - MASConstraint + +- (void)activate { + [self install]; +} + +- (void)deactivate { + [self uninstall]; +} + +- (void)install { + if (self.hasBeenInstalled) { + return; + } + + if ([self supportsActiveProperty] && self.layoutConstraint) { + self.layoutConstraint.active = YES; + [self.firstViewAttribute.view.mas_installedConstraints addObject:self]; + return; + } + + MAS_VIEW *firstLayoutItem = self.firstViewAttribute.item; + NSLayoutAttribute firstLayoutAttribute = self.firstViewAttribute.layoutAttribute; + MAS_VIEW *secondLayoutItem = self.secondViewAttribute.item; + NSLayoutAttribute secondLayoutAttribute = self.secondViewAttribute.layoutAttribute; + + // alignment attributes must have a secondViewAttribute + // therefore we assume that is refering to superview + // eg make.left.equalTo(@10) + if (!self.firstViewAttribute.isSizeAttribute && !self.secondViewAttribute) { + secondLayoutItem = self.firstViewAttribute.view.superview; + secondLayoutAttribute = firstLayoutAttribute; + } + + MASLayoutConstraint *layoutConstraint + = [MASLayoutConstraint constraintWithItem:firstLayoutItem + attribute:firstLayoutAttribute + relatedBy:self.layoutRelation + toItem:secondLayoutItem + attribute:secondLayoutAttribute + multiplier:self.layoutMultiplier + constant:self.layoutConstant]; + + layoutConstraint.priority = self.layoutPriority; + layoutConstraint.mas_key = self.mas_key; + + if (self.secondViewAttribute.view) { + MAS_VIEW *closestCommonSuperview = [self.firstViewAttribute.view mas_closestCommonSuperview:self.secondViewAttribute.view]; + NSAssert(closestCommonSuperview, + @"couldn't find a common superview for %@ and %@", + self.firstViewAttribute.view, self.secondViewAttribute.view); + self.installedView = closestCommonSuperview; + } else if (self.firstViewAttribute.isSizeAttribute) { + self.installedView = self.firstViewAttribute.view; + } else { + self.installedView = self.firstViewAttribute.view.superview; + } + + + MASLayoutConstraint *existingConstraint = nil; + if (self.updateExisting) { + existingConstraint = [self layoutConstraintSimilarTo:layoutConstraint]; + } + if (existingConstraint) { + // just update the constant + existingConstraint.constant = layoutConstraint.constant; + self.layoutConstraint = existingConstraint; + } else { + [self.installedView addConstraint:layoutConstraint]; + self.layoutConstraint = layoutConstraint; + [firstLayoutItem.mas_installedConstraints addObject:self]; + } +} + +- (MASLayoutConstraint *)layoutConstraintSimilarTo:(MASLayoutConstraint *)layoutConstraint { + // check if any constraints are the same apart from the only mutable property constant + + // go through constraints in reverse as we do not want to match auto-resizing or interface builder constraints + // and they are likely to be added first. + for (NSLayoutConstraint *existingConstraint in self.installedView.constraints.reverseObjectEnumerator) { + if (![existingConstraint isKindOfClass:MASLayoutConstraint.class]) continue; + if (existingConstraint.firstItem != layoutConstraint.firstItem) continue; + if (existingConstraint.secondItem != layoutConstraint.secondItem) continue; + if (existingConstraint.firstAttribute != layoutConstraint.firstAttribute) continue; + if (existingConstraint.secondAttribute != layoutConstraint.secondAttribute) continue; + if (existingConstraint.relation != layoutConstraint.relation) continue; + if (existingConstraint.multiplier != layoutConstraint.multiplier) continue; + if (existingConstraint.priority != layoutConstraint.priority) continue; + + return (id)existingConstraint; + } + return nil; +} + +- (void)uninstall { + if ([self supportsActiveProperty]) { + self.layoutConstraint.active = NO; + [self.firstViewAttribute.view.mas_installedConstraints removeObject:self]; + return; + } + + [self.installedView removeConstraint:self.layoutConstraint]; + self.layoutConstraint = nil; + self.installedView = nil; + + [self.firstViewAttribute.view.mas_installedConstraints removeObject:self]; +} + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/Masonry.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/Masonry.h" new file mode 100755 index 0000000..d1bd579 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/Masonry.h" @@ -0,0 +1,29 @@ +// +// Masonry.h +// Masonry +// +// Created by Jonas Budelmann on 20/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import + +//! Project version number for Masonry. +FOUNDATION_EXPORT double MasonryVersionNumber; + +//! Project version string for Masonry. +FOUNDATION_EXPORT const unsigned char MasonryVersionString[]; + +#import "MASUtilities.h" +#import "View+MASAdditions.h" +#import "View+MASShorthandAdditions.h" +#import "ViewController+MASAdditions.h" +#import "NSArray+MASAdditions.h" +#import "NSArray+MASShorthandAdditions.h" +#import "MASConstraint.h" +#import "MASCompositeConstraint.h" +#import "MASViewAttribute.h" +#import "MASViewConstraint.h" +#import "MASConstraintMaker.h" +#import "MASLayoutConstraint.h" +#import "NSLayoutConstraint+MASDebugAdditions.h" diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSArray+MASAdditions.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSArray+MASAdditions.h" new file mode 100755 index 0000000..83be23d --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSArray+MASAdditions.h" @@ -0,0 +1,72 @@ +// +// NSArray+MASAdditions.h +// +// +// Created by Daniel Hammond on 11/26/13. +// +// + +#import "MASUtilities.h" +#import "MASConstraintMaker.h" +#import "MASViewAttribute.h" + +typedef NS_ENUM(NSUInteger, MASAxisType) { + MASAxisTypeHorizontal, + MASAxisTypeVertical +}; + +@interface NSArray (MASAdditions) + +/** + * Creates a MASConstraintMaker with each view in the callee. + * Any constraints defined are added to the view or the appropriate superview once the block has finished executing on each view + * + * @param block scope within which you can build up the constraints which you wish to apply to each view. + * + * @return Array of created MASConstraints + */ +- (NSArray *)mas_makeConstraints:(void (^)(MASConstraintMaker *make))block; + +/** + * Creates a MASConstraintMaker with each view in the callee. + * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view. + * If an existing constraint exists then it will be updated instead. + * + * @param block scope within which you can build up the constraints which you wish to apply to each view. + * + * @return Array of created/updated MASConstraints + */ +- (NSArray *)mas_updateConstraints:(void (^)(MASConstraintMaker *make))block; + +/** + * Creates a MASConstraintMaker with each view in the callee. + * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view. + * All constraints previously installed for the views will be removed. + * + * @param block scope within which you can build up the constraints which you wish to apply to each view. + * + * @return Array of created/updated MASConstraints + */ +- (NSArray *)mas_remakeConstraints:(void (^)(MASConstraintMaker *make))block; + +/** + * distribute with fixed spacing + * + * @param axisType which axis to distribute items along + * @param fixedSpacing the spacing between each item + * @param leadSpacing the spacing before the first item and the container + * @param tailSpacing the spacing after the last item and the container + */ +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; + +/** + * distribute with fixed item size + * + * @param axisType which axis to distribute items along + * @param fixedItemLength the fixed length of each item + * @param leadSpacing the spacing before the first item and the container + * @param tailSpacing the spacing after the last item and the container + */ +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSArray+MASAdditions.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSArray+MASAdditions.m" new file mode 100755 index 0000000..e01e009 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSArray+MASAdditions.m" @@ -0,0 +1,164 @@ +// +// NSArray+MASAdditions.m +// +// +// Created by Daniel Hammond on 11/26/13. +// +// + +#import "NSArray+MASAdditions.h" +#import "View+MASAdditions.h" + +@implementation NSArray (MASAdditions) + +- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block { + NSMutableArray *constraints = [NSMutableArray array]; + for (MAS_VIEW *view in self) { + NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views"); + [constraints addObjectsFromArray:[view mas_makeConstraints:block]]; + } + return constraints; +} + +- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block { + NSMutableArray *constraints = [NSMutableArray array]; + for (MAS_VIEW *view in self) { + NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views"); + [constraints addObjectsFromArray:[view mas_updateConstraints:block]]; + } + return constraints; +} + +- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block { + NSMutableArray *constraints = [NSMutableArray array]; + for (MAS_VIEW *view in self) { + NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views"); + [constraints addObjectsFromArray:[view mas_remakeConstraints:block]]; + } + return constraints; +} + +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { + if (self.count < 2) { + NSAssert(self.count>1,@"views to distribute need to bigger than one"); + return; + } + + MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; + if (axisType == MASAxisTypeHorizontal) { + MAS_VIEW *prev; + for (int i = 0; i < self.count; i++) { + MAS_VIEW *v = self[i]; + [v mas_makeConstraints:^(MASConstraintMaker *make) { + if (prev) { + make.width.equalTo(prev); + make.left.equalTo(prev.mas_right).offset(fixedSpacing); + if (i == self.count - 1) {//last one + make.right.equalTo(tempSuperView).offset(-tailSpacing); + } + } + else {//first one + make.left.equalTo(tempSuperView).offset(leadSpacing); + } + + }]; + prev = v; + } + } + else { + MAS_VIEW *prev; + for (int i = 0; i < self.count; i++) { + MAS_VIEW *v = self[i]; + [v mas_makeConstraints:^(MASConstraintMaker *make) { + if (prev) { + make.height.equalTo(prev); + make.top.equalTo(prev.mas_bottom).offset(fixedSpacing); + if (i == self.count - 1) {//last one + make.bottom.equalTo(tempSuperView).offset(-tailSpacing); + } + } + else {//first one + make.top.equalTo(tempSuperView).offset(leadSpacing); + } + + }]; + prev = v; + } + } +} + +- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { + if (self.count < 2) { + NSAssert(self.count>1,@"views to distribute need to bigger than one"); + return; + } + + MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; + if (axisType == MASAxisTypeHorizontal) { + MAS_VIEW *prev; + for (int i = 0; i < self.count; i++) { + MAS_VIEW *v = self[i]; + [v mas_makeConstraints:^(MASConstraintMaker *make) { + if (prev) { + CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); + make.width.equalTo(@(fixedItemLength)); + if (i == self.count - 1) {//last one + make.right.equalTo(tempSuperView).offset(-tailSpacing); + } + else { + make.right.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); + } + } + else {//first one + make.left.equalTo(tempSuperView).offset(leadSpacing); + make.width.equalTo(@(fixedItemLength)); + } + }]; + prev = v; + } + } + else { + MAS_VIEW *prev; + for (int i = 0; i < self.count; i++) { + MAS_VIEW *v = self[i]; + [v mas_makeConstraints:^(MASConstraintMaker *make) { + if (prev) { + CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); + make.height.equalTo(@(fixedItemLength)); + if (i == self.count - 1) {//last one + make.bottom.equalTo(tempSuperView).offset(-tailSpacing); + } + else { + make.bottom.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); + } + } + else {//first one + make.top.equalTo(tempSuperView).offset(leadSpacing); + make.height.equalTo(@(fixedItemLength)); + } + }]; + prev = v; + } + } +} + +- (MAS_VIEW *)mas_commonSuperviewOfViews +{ + MAS_VIEW *commonSuperview = nil; + MAS_VIEW *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[MAS_VIEW class]]) { + MAS_VIEW *view = (MAS_VIEW *)object; + if (previousView) { + commonSuperview = [view mas_closestCommonSuperview:commonSuperview]; + } else { + commonSuperview = view; + } + previousView = view; + } + } + 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."); + return commonSuperview; +} + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSArray+MASShorthandAdditions.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSArray+MASShorthandAdditions.h" new file mode 100755 index 0000000..8b47369 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSArray+MASShorthandAdditions.h" @@ -0,0 +1,41 @@ +// +// NSArray+MASShorthandAdditions.h +// Masonry +// +// Created by Jonas Budelmann on 22/07/13. +// Copyright (c) 2013 Jonas Budelmann. All rights reserved. +// + +#import "NSArray+MASAdditions.h" + +#ifdef MAS_SHORTHAND + +/** + * Shorthand array additions without the 'mas_' prefixes, + * only enabled if MAS_SHORTHAND is defined + */ +@interface NSArray (MASShorthandAdditions) + +- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; +- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; +- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block; + +@end + +@implementation NSArray (MASShorthandAdditions) + +- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block { + return [self mas_makeConstraints:block]; +} + +- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block { + return [self mas_updateConstraints:block]; +} + +- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block { + return [self mas_remakeConstraints:block]; +} + +@end + +#endif diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSLayoutConstraint+MASDebugAdditions.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSLayoutConstraint+MASDebugAdditions.h" new file mode 100755 index 0000000..1279b4f --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSLayoutConstraint+MASDebugAdditions.h" @@ -0,0 +1,16 @@ +// +// NSLayoutConstraint+MASDebugAdditions.h +// Masonry +// +// Created by Jonas Budelmann on 3/08/13. +// Copyright (c) 2013 Jonas Budelmann. All rights reserved. +// + +#import "MASUtilities.h" + +/** + * makes debug and log output of NSLayoutConstraints more readable + */ +@interface NSLayoutConstraint (MASDebugAdditions) + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSLayoutConstraint+MASDebugAdditions.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSLayoutConstraint+MASDebugAdditions.m" new file mode 100755 index 0000000..3569cf8 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/NSLayoutConstraint+MASDebugAdditions.m" @@ -0,0 +1,146 @@ +// +// NSLayoutConstraint+MASDebugAdditions.m +// Masonry +// +// Created by Jonas Budelmann on 3/08/13. +// Copyright (c) 2013 Jonas Budelmann. All rights reserved. +// + +#import "NSLayoutConstraint+MASDebugAdditions.h" +#import "MASConstraint.h" +#import "MASLayoutConstraint.h" + +@implementation NSLayoutConstraint (MASDebugAdditions) + +#pragma mark - description maps + ++ (NSDictionary *)layoutRelationDescriptionsByValue { + static dispatch_once_t once; + static NSDictionary *descriptionMap; + dispatch_once(&once, ^{ + descriptionMap = @{ + @(NSLayoutRelationEqual) : @"==", + @(NSLayoutRelationGreaterThanOrEqual) : @">=", + @(NSLayoutRelationLessThanOrEqual) : @"<=", + }; + }); + return descriptionMap; +} + ++ (NSDictionary *)layoutAttributeDescriptionsByValue { + static dispatch_once_t once; + static NSDictionary *descriptionMap; + dispatch_once(&once, ^{ + descriptionMap = @{ + @(NSLayoutAttributeTop) : @"top", + @(NSLayoutAttributeLeft) : @"left", + @(NSLayoutAttributeBottom) : @"bottom", + @(NSLayoutAttributeRight) : @"right", + @(NSLayoutAttributeLeading) : @"leading", + @(NSLayoutAttributeTrailing) : @"trailing", + @(NSLayoutAttributeWidth) : @"width", + @(NSLayoutAttributeHeight) : @"height", + @(NSLayoutAttributeCenterX) : @"centerX", + @(NSLayoutAttributeCenterY) : @"centerY", + @(NSLayoutAttributeBaseline) : @"baseline", + +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + @(NSLayoutAttributeFirstBaseline) : @"firstBaseline", + @(NSLayoutAttributeLastBaseline) : @"lastBaseline", +#endif + +#if TARGET_OS_IPHONE || TARGET_OS_TV + @(NSLayoutAttributeLeftMargin) : @"leftMargin", + @(NSLayoutAttributeRightMargin) : @"rightMargin", + @(NSLayoutAttributeTopMargin) : @"topMargin", + @(NSLayoutAttributeBottomMargin) : @"bottomMargin", + @(NSLayoutAttributeLeadingMargin) : @"leadingMargin", + @(NSLayoutAttributeTrailingMargin) : @"trailingMargin", + @(NSLayoutAttributeCenterXWithinMargins) : @"centerXWithinMargins", + @(NSLayoutAttributeCenterYWithinMargins) : @"centerYWithinMargins", +#endif + + }; + + }); + return descriptionMap; +} + + ++ (NSDictionary *)layoutPriorityDescriptionsByValue { + static dispatch_once_t once; + static NSDictionary *descriptionMap; + dispatch_once(&once, ^{ +#if TARGET_OS_IPHONE || TARGET_OS_TV + descriptionMap = @{ + @(MASLayoutPriorityDefaultHigh) : @"high", + @(MASLayoutPriorityDefaultLow) : @"low", + @(MASLayoutPriorityDefaultMedium) : @"medium", + @(MASLayoutPriorityRequired) : @"required", + @(MASLayoutPriorityFittingSizeLevel) : @"fitting size", + }; +#elif TARGET_OS_MAC + descriptionMap = @{ + @(MASLayoutPriorityDefaultHigh) : @"high", + @(MASLayoutPriorityDragThatCanResizeWindow) : @"drag can resize window", + @(MASLayoutPriorityDefaultMedium) : @"medium", + @(MASLayoutPriorityWindowSizeStayPut) : @"window size stay put", + @(MASLayoutPriorityDragThatCannotResizeWindow) : @"drag cannot resize window", + @(MASLayoutPriorityDefaultLow) : @"low", + @(MASLayoutPriorityFittingSizeCompression) : @"fitting size", + @(MASLayoutPriorityRequired) : @"required", + }; +#endif + }); + return descriptionMap; +} + +#pragma mark - description override + ++ (NSString *)descriptionForObject:(id)obj { + if ([obj respondsToSelector:@selector(mas_key)] && [obj mas_key]) { + return [NSString stringWithFormat:@"%@:%@", [obj class], [obj mas_key]]; + } + return [NSString stringWithFormat:@"%@:%p", [obj class], obj]; +} + +- (NSString *)description { + NSMutableString *description = [[NSMutableString alloc] initWithString:@"<"]; + + [description appendString:[self.class descriptionForObject:self]]; + + [description appendFormat:@" %@", [self.class descriptionForObject:self.firstItem]]; + if (self.firstAttribute != NSLayoutAttributeNotAnAttribute) { + [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.firstAttribute)]]; + } + + [description appendFormat:@" %@", self.class.layoutRelationDescriptionsByValue[@(self.relation)]]; + + if (self.secondItem) { + [description appendFormat:@" %@", [self.class descriptionForObject:self.secondItem]]; + } + if (self.secondAttribute != NSLayoutAttributeNotAnAttribute) { + [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.secondAttribute)]]; + } + + if (self.multiplier != 1) { + [description appendFormat:@" * %g", self.multiplier]; + } + + if (self.secondAttribute == NSLayoutAttributeNotAnAttribute) { + [description appendFormat:@" %g", self.constant]; + } else { + if (self.constant) { + [description appendFormat:@" %@ %g", (self.constant < 0 ? @"-" : @"+"), ABS(self.constant)]; + } + } + + if (self.priority != MASLayoutPriorityRequired) { + [description appendFormat:@" ^%@", self.class.layoutPriorityDescriptionsByValue[@(self.priority)] ?: [NSNumber numberWithDouble:self.priority]]; + } + + [description appendString:@">"]; + return description; +} + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/View+MASAdditions.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/View+MASAdditions.h" new file mode 100755 index 0000000..ab1e8ae --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/View+MASAdditions.h" @@ -0,0 +1,101 @@ +// +// UIView+MASAdditions.h +// Masonry +// +// Created by Jonas Budelmann on 20/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import "MASUtilities.h" +#import "MASConstraintMaker.h" +#import "MASViewAttribute.h" + +/** + * Provides constraint maker block + * and convience methods for creating MASViewAttribute which are view + NSLayoutAttribute pairs + */ +@interface MAS_VIEW (MASAdditions) + +/** + * following properties return a new MASViewAttribute with current view and appropriate NSLayoutAttribute + */ +@property (nonatomic, strong, readonly) MASViewAttribute *mas_left; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_top; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_right; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottom; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_leading; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_trailing; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_width; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_height; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline; +@property (nonatomic, strong, readonly) MASViewAttribute *(^mas_attribute)(NSLayoutAttribute attr); + +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + +@property (nonatomic, strong, readonly) MASViewAttribute *mas_firstBaseline; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_lastBaseline; + +#endif + +#if TARGET_OS_IPHONE || TARGET_OS_TV + +@property (nonatomic, strong, readonly) MASViewAttribute *mas_leftMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_rightMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_topMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_leadingMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_trailingMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerXWithinMargins; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerYWithinMargins; + +#endif + +/** + * a key to associate with this view + */ +@property (nonatomic, strong) id mas_key; + +/** + * Finds the closest common superview between this view and another view + * + * @param view other view + * + * @return returns nil if common superview could not be found + */ +- (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view; + +/** + * Creates a MASConstraintMaker with the callee view. + * Any constraints defined are added to the view or the appropriate superview once the block has finished executing + * + * @param block scope within which you can build up the constraints which you wish to apply to the view. + * + * @return Array of created MASConstraints + */ +- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block; + +/** + * Creates a MASConstraintMaker with the callee view. + * Any constraints defined are added to the view or the appropriate superview once the block has finished executing. + * If an existing constraint exists then it will be updated instead. + * + * @param block scope within which you can build up the constraints which you wish to apply to the view. + * + * @return Array of created/updated MASConstraints + */ +- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block; + +/** + * Creates a MASConstraintMaker with the callee view. + * Any constraints defined are added to the view or the appropriate superview once the block has finished executing. + * All constraints previously installed for the view will be removed. + * + * @param block scope within which you can build up the constraints which you wish to apply to the view. + * + * @return Array of created/updated MASConstraints + */ +- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block; + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/View+MASAdditions.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/View+MASAdditions.m" new file mode 100755 index 0000000..b53b68d --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/View+MASAdditions.m" @@ -0,0 +1,166 @@ +// +// UIView+MASAdditions.m +// Masonry +// +// Created by Jonas Budelmann on 20/07/13. +// Copyright (c) 2013 cloudling. All rights reserved. +// + +#import "View+MASAdditions.h" +#import + +@implementation MAS_VIEW (MASAdditions) + +- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block { + self.translatesAutoresizingMaskIntoConstraints = NO; + MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self]; + block(constraintMaker); + return [constraintMaker install]; +} + +- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *))block { + self.translatesAutoresizingMaskIntoConstraints = NO; + MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self]; + constraintMaker.updateExisting = YES; + block(constraintMaker); + return [constraintMaker install]; +} + +- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block { + self.translatesAutoresizingMaskIntoConstraints = NO; + MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self]; + constraintMaker.removeExisting = YES; + block(constraintMaker); + return [constraintMaker install]; +} + +#pragma mark - NSLayoutAttribute properties + +- (MASViewAttribute *)mas_left { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeft]; +} + +- (MASViewAttribute *)mas_top { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTop]; +} + +- (MASViewAttribute *)mas_right { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRight]; +} + +- (MASViewAttribute *)mas_bottom { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottom]; +} + +- (MASViewAttribute *)mas_leading { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeading]; +} + +- (MASViewAttribute *)mas_trailing { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailing]; +} + +- (MASViewAttribute *)mas_width { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeWidth]; +} + +- (MASViewAttribute *)mas_height { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeHeight]; +} + +- (MASViewAttribute *)mas_centerX { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterX]; +} + +- (MASViewAttribute *)mas_centerY { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterY]; +} + +- (MASViewAttribute *)mas_baseline { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBaseline]; +} + +- (MASViewAttribute *(^)(NSLayoutAttribute))mas_attribute +{ + return ^(NSLayoutAttribute attr) { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:attr]; + }; +} + +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + +- (MASViewAttribute *)mas_firstBaseline { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeFirstBaseline]; +} +- (MASViewAttribute *)mas_lastBaseline { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLastBaseline]; +} + +#endif + +#if TARGET_OS_IPHONE || TARGET_OS_TV + +- (MASViewAttribute *)mas_leftMargin { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeftMargin]; +} + +- (MASViewAttribute *)mas_rightMargin { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRightMargin]; +} + +- (MASViewAttribute *)mas_topMargin { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTopMargin]; +} + +- (MASViewAttribute *)mas_bottomMargin { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottomMargin]; +} + +- (MASViewAttribute *)mas_leadingMargin { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeadingMargin]; +} + +- (MASViewAttribute *)mas_trailingMargin { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailingMargin]; +} + +- (MASViewAttribute *)mas_centerXWithinMargins { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterXWithinMargins]; +} + +- (MASViewAttribute *)mas_centerYWithinMargins { + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterYWithinMargins]; +} + +#endif + +#pragma mark - associated properties + +- (id)mas_key { + return objc_getAssociatedObject(self, @selector(mas_key)); +} + +- (void)setMas_key:(id)key { + objc_setAssociatedObject(self, @selector(mas_key), key, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - heirachy + +- (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view { + MAS_VIEW *closestCommonSuperview = nil; + + MAS_VIEW *secondViewSuperview = view; + while (!closestCommonSuperview && secondViewSuperview) { + MAS_VIEW *firstViewSuperview = self; + while (!closestCommonSuperview && firstViewSuperview) { + if (secondViewSuperview == firstViewSuperview) { + closestCommonSuperview = secondViewSuperview; + } + firstViewSuperview = firstViewSuperview.superview; + } + secondViewSuperview = secondViewSuperview.superview; + } + return closestCommonSuperview; +} + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/View+MASShorthandAdditions.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/View+MASShorthandAdditions.h" new file mode 100755 index 0000000..0446056 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/View+MASShorthandAdditions.h" @@ -0,0 +1,115 @@ +// +// UIView+MASShorthandAdditions.h +// Masonry +// +// Created by Jonas Budelmann on 22/07/13. +// Copyright (c) 2013 Jonas Budelmann. All rights reserved. +// + +#import "View+MASAdditions.h" + +#ifdef MAS_SHORTHAND + +/** + * Shorthand view additions without the 'mas_' prefixes, + * only enabled if MAS_SHORTHAND is defined + */ +@interface MAS_VIEW (MASShorthandAdditions) + +@property (nonatomic, strong, readonly) MASViewAttribute *left; +@property (nonatomic, strong, readonly) MASViewAttribute *top; +@property (nonatomic, strong, readonly) MASViewAttribute *right; +@property (nonatomic, strong, readonly) MASViewAttribute *bottom; +@property (nonatomic, strong, readonly) MASViewAttribute *leading; +@property (nonatomic, strong, readonly) MASViewAttribute *trailing; +@property (nonatomic, strong, readonly) MASViewAttribute *width; +@property (nonatomic, strong, readonly) MASViewAttribute *height; +@property (nonatomic, strong, readonly) MASViewAttribute *centerX; +@property (nonatomic, strong, readonly) MASViewAttribute *centerY; +@property (nonatomic, strong, readonly) MASViewAttribute *baseline; +@property (nonatomic, strong, readonly) MASViewAttribute *(^attribute)(NSLayoutAttribute attr); + +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + +@property (nonatomic, strong, readonly) MASViewAttribute *firstBaseline; +@property (nonatomic, strong, readonly) MASViewAttribute *lastBaseline; + +#endif + +#if TARGET_OS_IPHONE || TARGET_OS_TV + +@property (nonatomic, strong, readonly) MASViewAttribute *leftMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *rightMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *topMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *bottomMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *leadingMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *trailingMargin; +@property (nonatomic, strong, readonly) MASViewAttribute *centerXWithinMargins; +@property (nonatomic, strong, readonly) MASViewAttribute *centerYWithinMargins; + +#endif + +- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; +- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; +- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block; + +@end + +#define MAS_ATTR_FORWARD(attr) \ +- (MASViewAttribute *)attr { \ + return [self mas_##attr]; \ +} + +@implementation MAS_VIEW (MASShorthandAdditions) + +MAS_ATTR_FORWARD(top); +MAS_ATTR_FORWARD(left); +MAS_ATTR_FORWARD(bottom); +MAS_ATTR_FORWARD(right); +MAS_ATTR_FORWARD(leading); +MAS_ATTR_FORWARD(trailing); +MAS_ATTR_FORWARD(width); +MAS_ATTR_FORWARD(height); +MAS_ATTR_FORWARD(centerX); +MAS_ATTR_FORWARD(centerY); +MAS_ATTR_FORWARD(baseline); + +#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) + +MAS_ATTR_FORWARD(firstBaseline); +MAS_ATTR_FORWARD(lastBaseline); + +#endif + +#if TARGET_OS_IPHONE || TARGET_OS_TV + +MAS_ATTR_FORWARD(leftMargin); +MAS_ATTR_FORWARD(rightMargin); +MAS_ATTR_FORWARD(topMargin); +MAS_ATTR_FORWARD(bottomMargin); +MAS_ATTR_FORWARD(leadingMargin); +MAS_ATTR_FORWARD(trailingMargin); +MAS_ATTR_FORWARD(centerXWithinMargins); +MAS_ATTR_FORWARD(centerYWithinMargins); + +#endif + +- (MASViewAttribute *(^)(NSLayoutAttribute))attribute { + return [self mas_attribute]; +} + +- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block { + return [self mas_makeConstraints:block]; +} + +- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block { + return [self mas_updateConstraints:block]; +} + +- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block { + return [self mas_remakeConstraints:block]; +} + +@end + +#endif diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/ViewController+MASAdditions.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/ViewController+MASAdditions.h" new file mode 100755 index 0000000..79fd1fa --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/ViewController+MASAdditions.h" @@ -0,0 +1,30 @@ +// +// UIViewController+MASAdditions.h +// Masonry +// +// Created by Craig Siemens on 2015-06-23. +// +// + +#import "MASUtilities.h" +#import "MASConstraintMaker.h" +#import "MASViewAttribute.h" + +#ifdef MAS_VIEW_CONTROLLER + +@interface MAS_VIEW_CONTROLLER (MASAdditions) + +/** + * following properties return a new MASViewAttribute with appropriate UILayoutGuide and NSLayoutAttribute + */ +@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuide; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuide; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideTop; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideBottom; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideTop; +@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideBottom; + + +@end + +#endif diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/ViewController+MASAdditions.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/ViewController+MASAdditions.m" new file mode 100755 index 0000000..2f5139f --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Masonry/ViewController+MASAdditions.m" @@ -0,0 +1,39 @@ +// +// UIViewController+MASAdditions.m +// Masonry +// +// Created by Craig Siemens on 2015-06-23. +// +// + +#import "ViewController+MASAdditions.h" + +#ifdef MAS_VIEW_CONTROLLER + +@implementation MAS_VIEW_CONTROLLER (MASAdditions) + +- (MASViewAttribute *)mas_topLayoutGuide { + return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; +} +- (MASViewAttribute *)mas_topLayoutGuideTop { + return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeTop]; +} +- (MASViewAttribute *)mas_topLayoutGuideBottom { + return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; +} + +- (MASViewAttribute *)mas_bottomLayoutGuide { + return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; +} +- (MASViewAttribute *)mas_bottomLayoutGuideTop { + return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; +} +- (MASViewAttribute *)mas_bottomLayoutGuideBottom { + return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; +} + + + +@end + +#endif diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Search/Controller/YTSearchController.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Search/Controller/YTSearchController.m" deleted file mode 100644 index 37f98c1..0000000 --- "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Search/Controller/YTSearchController.m" +++ /dev/null @@ -1,38 +0,0 @@ -// -// YTSearchController.m -// 仿搜狗阅读 -// -// Created by Mac on 16/6/2. -// Copyright © 2016年 YinTokey. All rights reserved. -// - -#import "YTSearchController.h" - -@interface YTSearchController () - -- (IBAction)cancelBtnClick:(id)sender; - -@end - -@implementation YTSearchController - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.navigationItem.hidesBackButton = YES; - - -// [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"topline"] forBarMetrics:UIBarMetricsDefault]; -// NSDictionary *titleAttr = @{ -// NSForegroundColorAttributeName:[UIColor whiteColor], -// NSFontAttributeName:[UIFont systemFontOfSize:18] -// }; -// [self.navigationController.navigationBar setTitleTextAttributes:titleAttr]; -} - - - -- (IBAction)cancelBtnClick:(id)sender { - [self.navigationController popViewControllerAnimated:YES]; -} -@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/AppDelegate.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/AppDelegate.m" index 937125c..274fef1 100644 --- "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/AppDelegate.m" +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/AppDelegate.m" @@ -17,6 +17,8 @@ @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. + //防止界面跳转,出现黑块 + self.window.backgroundColor = [UIColor whiteColor]; return YES; } diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/Category/UIBarButtonItem+Extension.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/Category/UIBarButtonItem+Extension.h" new file mode 100644 index 0000000..69756f5 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/Category/UIBarButtonItem+Extension.h" @@ -0,0 +1,17 @@ +// +// UIBarButtonItem+Extension.h +// 仿搜狗阅读 +// +// Created by Mac on 16/6/3. +// Copyright © 2016年 YinTokey. All rights reserved. +// + +#import + +@interface UIBarButtonItem (Extension) + ++ (instancetype)barButtonItemWithTitle:(NSString *)title + target:(id)target + action:(SEL)action; + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/Category/UIBarButtonItem+Extension.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/Category/UIBarButtonItem+Extension.m" new file mode 100644 index 0000000..5a96096 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/Category/UIBarButtonItem+Extension.m" @@ -0,0 +1,26 @@ +// +// UIBarButtonItem+Extension.m +// 仿搜狗阅读 +// +// Created by Mac on 16/6/3. +// Copyright © 2016年 YinTokey. All rights reserved. +// + +#import "UIBarButtonItem+Extension.h" + +@implementation UIBarButtonItem (Extension) + ++ (instancetype)barButtonItemWithTitle:(NSString *)title + target:(id)target + action:(SEL)action { + UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 50, 40)]; //后期加入ipad,这个要调整 + button.titleLabel.textAlignment = NSTextAlignmentRight; + [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + button.titleLabel.font = [UIFont systemFontOfSize:16]; + [button setTitle:title forState:UIControlStateNormal]; + [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; + UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc]initWithCustomView:button]; + return barButtonItem; +} + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/PrefixHeader.pch" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/PrefixHeader.pch" new file mode 100644 index 0000000..e4d97d1 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Others/PrefixHeader.pch" @@ -0,0 +1,38 @@ +// +// PrefixHeader.pch +// 仿搜狗阅读 +// +// Created by Mac on 16/6/3. +// Copyright © 2016年 YinTokey. All rights reserved. +// + +#ifndef PrefixHeader_pch +#define PrefixHeader_pch + +// Include any system framework and library headers here that should be included in all compilation units. +// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. + +#import "YTSearchBar.h" +#import "UIBarButtonItem+Extension.h" + +#define YTUserDefaults [NSUserDefaults standardUserDefaults] +#define YTScreenBounds [UIScreen mainScreen].bounds +#define YTScreenWidth [UIScreen mainScreen].bounds.size.width +#define YTScreenHeight [UIScreen mainScreen].bounds.size.height + + + +#define WeakSelf __weak typeof(self) weakSelf = self; +/** + * 1.返回一个RGBA格式的UIColor对象 + */ +#define RGBA(r, g, b, a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a] + +/** + * 2.返回一个RGB格式的UIColor对象 + */ +#define RGB(r, g, b) RGBA(r, g, b, 1.0f) + + + +#endif /* PrefixHeader_pch */ diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Search/Controller/YTSearchController.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchController.h" similarity index 98% rename from "\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Search/Controller/YTSearchController.h" rename to "\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchController.h" index 06511cd..88c0aa7 100644 --- "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Lib/Search/Controller/YTSearchController.h" +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchController.h" @@ -8,6 +8,9 @@ #import + @interface YTSearchController : UIViewController + + @end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchController.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchController.m" new file mode 100644 index 0000000..0f5365f --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchController.m" @@ -0,0 +1,60 @@ +// +// YTSearchController.m +// 仿搜狗阅读 +// +// Created by Mac on 16/6/2. +// Copyright © 2016年 YinTokey. All rights reserved. +// + +#import "YTSearchController.h" + +@interface YTSearchController () + + +- (IBAction)cancelBtnClick:(id)sender; + + +@end + +@implementation YTSearchController + +- (void)viewWillAppear:(BOOL)animated{ + // self.navigationItem.leftBarButtonItem = nil; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + // self.navigationItem.leftBarButtonItem = nil; + // self.navigationItem.hidesBackButton = YES; + + // self.navigationController.navigationBar.translucent = NO; + + [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"topline"] forBarMetrics:UIBarMetricsDefault]; + NSDictionary *titleAttr = @{ + NSForegroundColorAttributeName:[UIColor whiteColor], + NSFontAttributeName:[UIFont systemFontOfSize:18] + }; + [self.navigationController.navigationBar setTitleTextAttributes:titleAttr]; +} + + + +- (IBAction)cancelBtnClick:(id)sender { + + CATransition* transition = [CATransition animation]; + transition.duration = 0.5; + transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade + transition.subtype = kCATransitionFromBottom; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom + [self.navigationController.view.layer addAnimation:transition forKey:nil]; + [[self navigationController] popViewControllerAnimated:NO]; + + + +} + + + + + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchViewController.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchViewController.h" new file mode 100644 index 0000000..f3e1189 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchViewController.h" @@ -0,0 +1,13 @@ +// +// YTSearchViewController.h +// 仿搜狗阅读 +// +// Created by Mac on 16/6/3. +// Copyright © 2016年 YinTokey. All rights reserved. +// + +#import + +@interface YTSearchViewController : UITableViewController + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchViewController.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchViewController.m" new file mode 100644 index 0000000..06aa376 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/Controller/YTSearchViewController.m" @@ -0,0 +1,141 @@ +// +// YTSearchViewController.m +// 仿搜狗阅读 +// +// Created by Mac on 16/6/3. +// Copyright © 2016年 YinTokey. All rights reserved. +// + +#import "YTSearchViewController.h" +#import "Masonry.h" +#import "YTSearchFooter.h" + + +@interface YTSearchViewController () + +@property (nonatomic, strong) YTSearchBar *searchBar; +@property (nonatomic, copy) NSString *searchContent; // 搜索内容 +@property (nonatomic, strong) YTSearchFooter *footer; // 推荐搜索 +@property (nonatomic, strong) NSArray *hotSearchWords; // 推荐搜索关键词 + +@end + +@implementation YTSearchViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + + _hotSearchWords = @[@"完美世界",@"大主宰",@"雪鹰领主",@"龙王传说",@"校花的贴身高手",@"武炼巅峰",@"帝霸",@"超品相师",@"武逆",@"换一换" ]; + + self.tableView.bounces = NO; + + [self setupNavBar]; + [self setupFooter]; + [self setupTableView]; + + //添加手势相应,输textfield时,点击其他区域,键盘消失 + UITapGestureRecognizer *tapGr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewTapped:)]; + tapGr.cancelsTouchesInView = NO; + [self.view addGestureRecognizer:tapGr]; + + // Uncomment the following line to preserve selection between presentations. + // self.clearsSelectionOnViewWillAppear = NO; + + // Uncomment the following line to display an Edit button in the navigation bar for this view controller. + // self.navigationItem.rightBarButtonItem = self.editButtonItem; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { +#warning Incomplete implementation, return the number of sections + return 0; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { +#warning Incomplete implementation, return the number of rows + return 0; +} + +#pragma mark - 属性 + +- (void)setupNavBar { + self.navigationItem.leftBarButtonItem = nil; + self.navigationItem.hidesBackButton = YES; + self.navigationItem.rightBarButtonItem = [UIBarButtonItem barButtonItemWithTitle:@"取消" + target:self + action:@selector(cancel)]; + + self.searchBar = [YTSearchBar searchBarWithPlaceholder:@"搜索书城图书"]; + + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(400 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{ + [self.searchBar becomeFirstResponder]; + }); + // [self.searchBar becomeFirstResponder]; + self.navigationItem.titleView = self.searchBar; + + __weak YTSearchBar *wSearchBar = self.searchBar; + WeakSelf; + self.searchBar.searchBarTextDidChangedBlock = ^{ // 文本编辑回调 + weakSelf.searchContent = wSearchBar.text; + [weakSelf.tableView reloadData]; // 时刻刷新界面 + }; + self.searchBar.searchBarDidSearchBlock = ^{ // 搜索回调 +// [XCFSearchKeywordsTool addNewWord:wSearchBar.text]; +// [weakSelf pushResultVCWithResult:[NSString stringWithFormat:@"%@ \n %@", weakSelf.typeString[0], wSearchBar.text]]; + }; +} + +- (void)setupFooter{ + YTSearchFooter *footer = [[YTSearchFooter alloc] initWithFrame:CGRectMake(0, 0, YTScreenWidth, 270)]; + footer.hidden = self.searchContent.length; + footer.keywords = self.hotSearchWords; + WeakSelf; + // 点击回调 点击就搜索 + footer.searchCallBack = ^(NSUInteger index) { + NSLog(@"search"); +// [XCFSearchKeywordsTool addNewWord:weakSelf.hotSearchWords[index]]; +// NSString *displayString = [NSString stringWithFormat:@"%@:%@", weakSelf.typeString[0], weakSelf.hotSearchWords[index]]; +// [weakSelf pushResultVCWithResult:displayString]; + }; + //点击换一换,回调,改变数组 + footer.changeKeyWord = ^(NSUInteger index){ + NSLog(@"change"); + }; + + // self.tableView.tableFooterView = footer; + self.tableView.tableHeaderView = footer; + self.footer = footer; + + +} + +- (void)setupTableView { + self.tableView.sectionHeaderHeight = 0.1; + self.tableView.sectionFooterHeight = 0.1; +} + +//点击空白,键盘消失 +-(void)viewTapped:(UITapGestureRecognizer*)tapGr +{ + [self.searchBar resignFirstResponder]; + +} + +-(void)cancel{ + CATransition* transition = [CATransition animation]; + transition.duration = 0.5; + transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade + transition.subtype = kCATransitionFromBottom; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom + [self.navigationController.view.layer addAnimation:transition forKey:nil]; + [[self navigationController] popViewControllerAnimated:NO]; +} +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchBar.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchBar.h" new file mode 100644 index 0000000..5039e3a --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchBar.h" @@ -0,0 +1,18 @@ +// +// YTSearchBar.h +// 仿搜狗阅读 +// +// Created by Mac on 16/6/3. +// Copyright © 2016年 YinTokey. All rights reserved. +// + +#import + +@interface YTSearchBar : UISearchBar + +@property (nonatomic, copy) void (^searchBarShouldBeginEditingBlock)(); // 点击回调 +@property (nonatomic, copy) void (^searchBarTextDidChangedBlock)(); // 编辑回调 +@property (nonatomic, copy) void (^searchBarDidSearchBlock)(); // 编辑回调 + ++ (YTSearchBar *)searchBarWithPlaceholder:(NSString *)placeholder; +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchBar.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchBar.m" new file mode 100644 index 0000000..8d876d3 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchBar.m" @@ -0,0 +1,62 @@ +// +// YTSearchBar.m +// 仿搜狗阅读 +// +// Created by Mac on 16/6/3. +// Copyright © 2016年 YinTokey. All rights reserved. +// + +#import "YTSearchBar.h" + +@interface YTSearchBar () + +@end + + +@implementation YTSearchBar + ++ (YTSearchBar *)searchBarWithPlaceholder:(NSString *)placeholder { + YTSearchBar *searchBar = [[YTSearchBar alloc] init]; + searchBar.delegate = searchBar; + searchBar.placeholder = placeholder; + searchBar.tintColor = [UIColor whiteColor]; + [searchBar setImage:[UIImage imageNamed:@"search_sousuoicon"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; + UIView *searchBarSub = searchBar.subviews[0]; + for (UIView *subView in searchBarSub.subviews) { + + if ([subView isKindOfClass:NSClassFromString(@"UISearchBarTextField")]) { + [subView setBackgroundColor:RGB(196, 30, 28)]; + + } + + if ([subView isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) { + [subView removeFromSuperview]; + } + + if ([subView isKindOfClass:[UITextField class]]) { + UITextField *textField = (UITextField*)subView; + textField.textColor = [UIColor whiteColor]; + [textField setValue:[UIColor whiteColor] forKeyPath:@"_placeholderLabel.textColor"]; + textField.borderStyle = UITextBorderStyleNone; + } + } + + + return searchBar; +} + +- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar { + !self.searchBarShouldBeginEditingBlock ? : self.searchBarShouldBeginEditingBlock(); + return YES; +} + +- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { + !self.searchBarTextDidChangedBlock ? : self.searchBarTextDidChangedBlock(); +} + +- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { + !self.searchBarDidSearchBlock ? : self.searchBarDidSearchBlock(); +} + + +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchFooter.h" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchFooter.h" new file mode 100644 index 0000000..2fa2abc --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchFooter.h" @@ -0,0 +1,16 @@ +// +// YTSearchFooter.h +// 仿搜狗阅读 +// +// Created by Mac on 16/6/3. +// Copyright © 2016年 YinTokey. All rights reserved. +// + +#import + +@interface YTSearchFooter : UIView + +@property (nonatomic, strong) NSArray *keywords; // 推荐搜索词 +@property (nonatomic, copy) void (^searchCallBack)(NSUInteger); // 点击按钮的搜索回调 +@property (nonatomic, copy) void (^changeKeyWord)(NSUInteger); // 点击最后一个按钮,换搜索词回调 +@end diff --git "a/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchFooter.m" "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchFooter.m" new file mode 100644 index 0000000..99c8075 --- /dev/null +++ "b/\344\273\277\346\220\234\347\213\227\351\230\205\350\257\273/Classes/Search/View/YTSearchFooter.m" @@ -0,0 +1,92 @@ +// +// YTSearchFooter.m +// 仿搜狗阅读 +// +// Created by Mac on 16/6/3. +// Copyright © 2016年 YinTokey. All rights reserved. +// + +#import "YTSearchFooter.h" +#import "Masonry.h" + +@interface YTSearchFooter() + +@property (nonatomic, strong) UIView *buttonView; // 按钮数组 + +@end + +@implementation YTSearchFooter + +static NSInteger const kButtonCount = 10; + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + + UIView *view = [[UIView alloc] init]; + view.backgroundColor = [UIColor whiteColor]; + [self addSubview:view]; + [view mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.left.right.equalTo(self); + make.height.equalTo(@(0)); + }]; + + _buttonView = [[UIView alloc] init]; + _buttonView.backgroundColor = RGB(196, 196, 196); + [self addSubview:_buttonView]; + [_buttonView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.equalTo(self); + make.top.equalTo(view.mas_bottom); + //make.height 与按钮分割线相关,296是iphone5上刚刚好的数值 + make.height.equalTo(@(261)); + }]; + + NSInteger lineCount = 2; + CGFloat width = (YTScreenWidth-2) / lineCount; + CGFloat height = (105-3) / lineCount; + + CGFloat margin = 1; + CGFloat x = 0; + CGFloat y = 0; + + for (NSInteger index = 0; index < kButtonCount; index++) { + NSInteger line = index / lineCount; + NSInteger colunms = index % lineCount; + x = (width + margin) * colunms; + y = margin + (height + margin) * line; + UIButton *button = [[UIButton alloc] init]; + button.frame = CGRectMake(x, y, width, height); + button.backgroundColor = [UIColor whiteColor]; + button.tag = index; + button.titleLabel.font = [UIFont systemFontOfSize:14]; + if (index == 9) { + [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; + [button addTarget:self action:@selector(changeKeyWord:) forControlEvents:UIControlEventTouchUpInside]; + }else{ + [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; + [button addTarget:self action:@selector(search:) forControlEvents:UIControlEventTouchUpInside]; + } + [_buttonView addSubview:button]; + //[button addTarget:self action:@selector(search:) forControlEvents:UIControlEventTouchUpInside]; + } + + } + return self; +} + +- (void)search:(UIButton *)sender { + !self.searchCallBack ? : self.searchCallBack(sender.tag); +} + +- (void)changeKeyWord:(UIButton *)sender { + !self.changeKeyWord ? : self.changeKeyWord(sender.tag); +} + +- (void)setKeywords:(NSArray *)keywords { + _keywords = keywords; + for (NSInteger index=0; index