├── .gitignore ├── CONTRIBUTING.md ├── KSPAutomaticHeightCalculationTableCellView.podspec ├── KSPAutomaticHeightCalculationTableCellView.xcodeproj └── project.pbxproj ├── LICENSE.md ├── README.md ├── Sample ├── Resources │ ├── AHCMessageTableCellView.xib │ ├── AHCMessagesView.xib │ ├── AHCUserTableCellView.xib │ ├── AHCUsersView.xib │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ └── MainMenu.xib │ ├── Info.plist │ ├── Messages.plist │ ├── Users.plist │ └── Users.xcassets │ │ ├── 079f2a7c99f9514e44fbff57468a051dddcda4ea.imageset │ │ ├── 079f2a7c99f9514e44fbff57468a051dddcda4ea.jpg │ │ └── Contents.json │ │ ├── 21bfc3a4ef1fdd04843c7ab3e369548873b2bb32.imageset │ │ ├── 21bfc3a4ef1fdd04843c7ab3e369548873b2bb32.jpg │ │ └── Contents.json │ │ ├── 22ca6c3b376c0db48ece8a330b3ececacee3202b.imageset │ │ ├── 22ca6c3b376c0db48ece8a330b3ececacee3202b.jpg │ │ └── Contents.json │ │ ├── 29c5f52c7fcfb870b4a22b4477fd61162b0c0813.imageset │ │ ├── 29c5f52c7fcfb870b4a22b4477fd61162b0c0813.jpg │ │ └── Contents.json │ │ ├── 3a65d049905d2b7abb60f7e4a6195433b3485c64.imageset │ │ ├── 3a65d049905d2b7abb60f7e4a6195433b3485c64.jpg │ │ └── Contents.json │ │ ├── 5f9654a329bfa919b0b3907efb54ece76b16328f.imageset │ │ ├── 5f9654a329bfa919b0b3907efb54ece76b16328f.jpg │ │ └── Contents.json │ │ ├── 6f368cf70844e68b8f68484fe037a13dbab4d719.imageset │ │ ├── 6f368cf70844e68b8f68484fe037a13dbab4d719.jpg │ │ └── Contents.json │ │ ├── 92b3949de0d021744ff38db72c1ea3c3b6e15552.imageset │ │ ├── 92b3949de0d021744ff38db72c1ea3c3b6e15552.jpg │ │ └── Contents.json │ │ ├── 9b90c3e22c9c859bf8ffa31ca016011d7944499c.imageset │ │ ├── 9b90c3e22c9c859bf8ffa31ca016011d7944499c.jpg │ │ └── Contents.json │ │ ├── 9e5403114811093818a8daa5d9a1f95edbaff465.imageset │ │ ├── 9e5403114811093818a8daa5d9a1f95edbaff465.jpg │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── b197acb806bb016fbd90d1a0f6011c6cafb0a71c.imageset │ │ ├── Contents.json │ │ └── b197acb806bb016fbd90d1a0f6011c6cafb0a71c.jpg │ │ ├── c08ddc798a249f1aaafff96bcf48ba5622e48bae.imageset │ │ ├── Contents.json │ │ └── c08ddc798a249f1aaafff96bcf48ba5622e48bae.jpg │ │ ├── c3f7a2e83db7ee9ede31377dabf10c1745787653.imageset │ │ ├── Contents.json │ │ └── c3f7a2e83db7ee9ede31377dabf10c1745787653.jpg │ │ ├── d2dcdd803676fa25d2a0ab847dd78d25c4711f81.imageset │ │ ├── Contents.json │ │ └── d2dcdd803676fa25d2a0ab847dd78d25c4711f81.jpg │ │ ├── dff85d5459b00c277b1f72f800d8ac4b389acffa.imageset │ │ ├── Contents.json │ │ └── dff85d5459b00c277b1f72f800d8ac4b389acffa.jpg │ │ ├── eb67acf37daeecb670e5a2929f722dae0ef046ed.imageset │ │ ├── Contents.json │ │ └── eb67acf37daeecb670e5a2929f722dae0ef046ed.jpg │ │ ├── f732eac5da70e26d366cc1cde3674d721657a78e.imageset │ │ ├── Contents.json │ │ └── f732eac5da70e26d366cc1cde3674d721657a78e.jpg │ │ └── fe989b5336a096c9f73a38c73b05f0c6822d553d.imageset │ │ ├── Contents.json │ │ └── fe989b5336a096c9f73a38c73b05f0c6822d553d.jpg ├── Screenshot.png └── Sources │ ├── AHCMessageTableCellView+Private.h │ ├── AHCMessageTableCellView.h │ ├── AHCMessageTableCellView.m │ ├── AHCMessagesViewController+Private.h │ ├── AHCMessagesViewController.h │ ├── AHCMessagesViewController.m │ ├── AHCUser+Private.h │ ├── AHCUser.h │ ├── AHCUser.m │ ├── AHCUserTableCellView+Private.h │ ├── AHCUserTableCellView.h │ ├── AHCUserTableCellView.m │ ├── AHCUsersViewController+Private.h │ ├── AHCUsersViewController.h │ ├── AHCUsersViewController.m │ ├── AppDelegate.h │ ├── AppDelegate.m │ └── main.m └── Sources ├── KSPAutomaticHeightCalculationTableCellView+Private.h ├── KSPAutomaticHeightCalculationTableCellView.h └── KSPAutomaticHeightCalculationTableCellView.m /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | *.moved-aside 17 | DerivedData 18 | *.xcuserstate 19 | *.xcworkspace 20 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for your interest in the project! 4 | 5 | Please review the following pages before making changes: 6 | * [Cocoa Coding Guidelines](https://github.com/konstantinpavlikhin/CocoaCodingGuidelines) 7 | -------------------------------------------------------------------------------- /KSPAutomaticHeightCalculationTableCellView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | 3 | spec.name = 'KSPAutomaticHeightCalculationTableCellView' 4 | 5 | spec.version = '1.3.0' 6 | 7 | spec.authors = {'Konstantin Pavlikhin' => 'k.pavlikhin@gmail.com'} 8 | 9 | spec.social_media_url = 'https://twitter.com/kpavlikhin' 10 | 11 | spec.license = {:type => 'MIT', :file => 'LICENSE.md'} 12 | 13 | spec.homepage = 'https://github.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView' 14 | 15 | spec.source = {:git => 'https://github.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView.git', :tag => "#{spec.version}"} 16 | 17 | spec.summary = 'A useful superclass for a custom view-based NSTableViews cell.' 18 | 19 | spec.platform = :osx, "10.11" 20 | 21 | spec.osx.deployment_target = "10.8" 22 | 23 | spec.requires_arc = true 24 | 25 | spec.source_files = 'Sources/*.{h,m}' 26 | 27 | end 28 | -------------------------------------------------------------------------------- /KSPAutomaticHeightCalculationTableCellView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B57793DC1D7812CB00F92D7E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B57793D71D7812BA00F92D7E /* AppDelegate.m */; }; 11 | B57793DD1D7812CB00F92D7E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B57793D81D7812BA00F92D7E /* main.m */; }; 12 | B57793DF1D7812EA00F92D7E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B57793DE1D7812EA00F92D7E /* Assets.xcassets */; }; 13 | B57793E21D7812F300F92D7E /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = B57793E01D7812F300F92D7E /* MainMenu.xib */; }; 14 | B57793E71D7814F200F92D7E /* AHCUsersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B57793E61D7814F200F92D7E /* AHCUsersViewController.m */; }; 15 | B57793EB1D78155500F92D7E /* AHCUsersView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B57793EA1D78155500F92D7E /* AHCUsersView.xib */; }; 16 | B57793EF1D78197200F92D7E /* AHCUserTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = B57793EE1D78197200F92D7E /* AHCUserTableCellView.m */; }; 17 | B57793F21D7819C900F92D7E /* AHCUserTableCellView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B57793F11D7819C900F92D7E /* AHCUserTableCellView.xib */; }; 18 | B57793F31D781B1200F92D7E /* libKSPAutomaticHeightCalculationTableCellView.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B5CD03541BCBAC0C0072878A /* libKSPAutomaticHeightCalculationTableCellView.dylib */; }; 19 | B57793F71D781C9500F92D7E /* AHCUser.m in Sources */ = {isa = PBXBuildFile; fileRef = B57793F61D781C9500F92D7E /* AHCUser.m */; }; 20 | B57793FA1D781FA000F92D7E /* Users.plist in Resources */ = {isa = PBXBuildFile; fileRef = B57793F91D781FA000F92D7E /* Users.plist */; }; 21 | B57793FC1D78229F00F92D7E /* Users.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B57793FB1D78229F00F92D7E /* Users.xcassets */; }; 22 | B57794001D78358900F92D7E /* AHCMessagesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B57793FF1D78358900F92D7E /* AHCMessagesViewController.m */; }; 23 | B57794031D78360D00F92D7E /* AHCMessagesView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B57794021D78360D00F92D7E /* AHCMessagesView.xib */; }; 24 | B57794051D783A8400F92D7E /* Messages.plist in Resources */ = {isa = PBXBuildFile; fileRef = B57794041D783A8400F92D7E /* Messages.plist */; }; 25 | B57794091D783E1400F92D7E /* AHCMessageTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = B57794081D783E1400F92D7E /* AHCMessageTableCellView.m */; }; 26 | B577940C1D783E6500F92D7E /* AHCMessageTableCellView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B577940B1D783E6500F92D7E /* AHCMessageTableCellView.xib */; }; 27 | B5CD035E1BCBAC210072878A /* KSPAutomaticHeightCalculationTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = B5B6330A1AA1DF9B00BBF084 /* KSPAutomaticHeightCalculationTableCellView.m */; }; 28 | B5CD035F1BCBB0B00072878A /* KSPAutomaticHeightCalculationTableCellView.h in Headers */ = {isa = PBXBuildFile; fileRef = B5B633091AA1DF9B00BBF084 /* KSPAutomaticHeightCalculationTableCellView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 29 | B5CD03601BCBB1430072878A /* KSPAutomaticHeightCalculationTableCellView+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = B5B6330C1AA1DF9B00BBF084 /* KSPAutomaticHeightCalculationTableCellView+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | B57793C41D78112700F92D7E /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | B57793D61D7812BA00F92D7E /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Sample/Sources/AppDelegate.h; sourceTree = ""; }; 35 | B57793D71D7812BA00F92D7E /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Sample/Sources/AppDelegate.m; sourceTree = ""; }; 36 | B57793D81D7812BA00F92D7E /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Sample/Sources/main.m; sourceTree = ""; }; 37 | B57793DE1D7812EA00F92D7E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Sample/Resources/Assets.xcassets; sourceTree = ""; }; 38 | B57793E11D7812F300F92D7E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Sample/Resources/Base.lproj/MainMenu.xib; sourceTree = ""; }; 39 | B57793E31D78134900F92D7E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Sample/Resources/Info.plist; sourceTree = ""; }; 40 | B57793E51D7814F200F92D7E /* AHCUsersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AHCUsersViewController.h; path = Sample/Sources/AHCUsersViewController.h; sourceTree = ""; }; 41 | B57793E61D7814F200F92D7E /* AHCUsersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AHCUsersViewController.m; path = Sample/Sources/AHCUsersViewController.m; sourceTree = ""; }; 42 | B57793E91D78152900F92D7E /* AHCUsersViewController+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "AHCUsersViewController+Private.h"; path = "Sample/Sources/AHCUsersViewController+Private.h"; sourceTree = ""; }; 43 | B57793EA1D78155500F92D7E /* AHCUsersView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = AHCUsersView.xib; path = Sample/Resources/AHCUsersView.xib; sourceTree = ""; }; 44 | B57793ED1D78197200F92D7E /* AHCUserTableCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AHCUserTableCellView.h; path = Sample/Sources/AHCUserTableCellView.h; sourceTree = ""; }; 45 | B57793EE1D78197200F92D7E /* AHCUserTableCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AHCUserTableCellView.m; path = Sample/Sources/AHCUserTableCellView.m; sourceTree = ""; }; 46 | B57793F01D7819A800F92D7E /* AHCUserTableCellView+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "AHCUserTableCellView+Private.h"; path = "Sample/Sources/AHCUserTableCellView+Private.h"; sourceTree = ""; }; 47 | B57793F11D7819C900F92D7E /* AHCUserTableCellView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = AHCUserTableCellView.xib; path = Sample/Resources/AHCUserTableCellView.xib; sourceTree = ""; }; 48 | B57793F51D781C9500F92D7E /* AHCUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AHCUser.h; path = Sample/Sources/AHCUser.h; sourceTree = ""; }; 49 | B57793F61D781C9500F92D7E /* AHCUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AHCUser.m; path = Sample/Sources/AHCUser.m; sourceTree = ""; }; 50 | B57793F81D781CAB00F92D7E /* AHCUser+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "AHCUser+Private.h"; path = "Sample/Sources/AHCUser+Private.h"; sourceTree = ""; }; 51 | B57793F91D781FA000F92D7E /* Users.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Users.plist; path = Sample/Resources/Users.plist; sourceTree = ""; }; 52 | B57793FB1D78229F00F92D7E /* Users.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Users.xcassets; path = Sample/Resources/Users.xcassets; sourceTree = ""; }; 53 | B57793FE1D78358900F92D7E /* AHCMessagesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AHCMessagesViewController.h; path = Sample/Sources/AHCMessagesViewController.h; sourceTree = ""; }; 54 | B57793FF1D78358900F92D7E /* AHCMessagesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AHCMessagesViewController.m; path = Sample/Sources/AHCMessagesViewController.m; sourceTree = ""; }; 55 | B57794011D7835E600F92D7E /* AHCMessagesViewController+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "AHCMessagesViewController+Private.h"; path = "Sample/Sources/AHCMessagesViewController+Private.h"; sourceTree = ""; }; 56 | B57794021D78360D00F92D7E /* AHCMessagesView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = AHCMessagesView.xib; path = Sample/Resources/AHCMessagesView.xib; sourceTree = ""; }; 57 | B57794041D783A8400F92D7E /* Messages.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Messages.plist; path = Sample/Resources/Messages.plist; sourceTree = ""; }; 58 | B57794071D783E1400F92D7E /* AHCMessageTableCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AHCMessageTableCellView.h; path = Sample/Sources/AHCMessageTableCellView.h; sourceTree = ""; }; 59 | B57794081D783E1400F92D7E /* AHCMessageTableCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AHCMessageTableCellView.m; path = Sample/Sources/AHCMessageTableCellView.m; sourceTree = ""; }; 60 | B577940A1D783E2F00F92D7E /* AHCMessageTableCellView+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "AHCMessageTableCellView+Private.h"; path = "Sample/Sources/AHCMessageTableCellView+Private.h"; sourceTree = ""; }; 61 | B577940B1D783E6500F92D7E /* AHCMessageTableCellView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = AHCMessageTableCellView.xib; path = Sample/Resources/AHCMessageTableCellView.xib; sourceTree = ""; }; 62 | B5B633091AA1DF9B00BBF084 /* KSPAutomaticHeightCalculationTableCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = KSPAutomaticHeightCalculationTableCellView.h; path = Sources/KSPAutomaticHeightCalculationTableCellView.h; sourceTree = ""; }; 63 | B5B6330A1AA1DF9B00BBF084 /* KSPAutomaticHeightCalculationTableCellView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = KSPAutomaticHeightCalculationTableCellView.m; path = Sources/KSPAutomaticHeightCalculationTableCellView.m; sourceTree = ""; }; 64 | B5B6330B1AA1DF9B00BBF084 /* KSPAutomaticHeightCalculationTableCellView.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = KSPAutomaticHeightCalculationTableCellView.podspec; sourceTree = ""; }; 65 | B5B6330C1AA1DF9B00BBF084 /* KSPAutomaticHeightCalculationTableCellView+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "KSPAutomaticHeightCalculationTableCellView+Private.h"; path = "Sources/KSPAutomaticHeightCalculationTableCellView+Private.h"; sourceTree = ""; }; 66 | B5B6330D1AA1DF9B00BBF084 /* LICENSE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = ""; }; 67 | B5B6330E1AA1DF9B00BBF084 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 68 | B5CD03541BCBAC0C0072878A /* libKSPAutomaticHeightCalculationTableCellView.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libKSPAutomaticHeightCalculationTableCellView.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | /* End PBXFileReference section */ 70 | 71 | /* Begin PBXFrameworksBuildPhase section */ 72 | B57793C11D78112700F92D7E /* Frameworks */ = { 73 | isa = PBXFrameworksBuildPhase; 74 | buildActionMask = 2147483647; 75 | files = ( 76 | B57793F31D781B1200F92D7E /* libKSPAutomaticHeightCalculationTableCellView.dylib in Frameworks */, 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | B5CD03511BCBAC0C0072878A /* Frameworks */ = { 81 | isa = PBXFrameworksBuildPhase; 82 | buildActionMask = 2147483647; 83 | files = ( 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | /* End PBXFrameworksBuildPhase section */ 88 | 89 | /* Begin PBXGroup section */ 90 | B57793D51D78129500F92D7E /* Sample */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | B57793E81D78150B00F92D7E /* UsersViewController */, 94 | B57793FD1D7834F200F92D7E /* MessagesViewController */, 95 | B57793D61D7812BA00F92D7E /* AppDelegate.h */, 96 | B57793D71D7812BA00F92D7E /* AppDelegate.m */, 97 | B57793D81D7812BA00F92D7E /* main.m */, 98 | B57793E31D78134900F92D7E /* Info.plist */, 99 | B57793E01D7812F300F92D7E /* MainMenu.xib */, 100 | B57793DE1D7812EA00F92D7E /* Assets.xcassets */, 101 | ); 102 | name = Sample; 103 | sourceTree = ""; 104 | }; 105 | B57793E81D78150B00F92D7E /* UsersViewController */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | B57793F41D781C6F00F92D7E /* User */, 109 | B57793EC1D78194900F92D7E /* UserTableCellView */, 110 | B57793EA1D78155500F92D7E /* AHCUsersView.xib */, 111 | B57793E51D7814F200F92D7E /* AHCUsersViewController.h */, 112 | B57793E91D78152900F92D7E /* AHCUsersViewController+Private.h */, 113 | B57793E61D7814F200F92D7E /* AHCUsersViewController.m */, 114 | B57793F91D781FA000F92D7E /* Users.plist */, 115 | B57793FB1D78229F00F92D7E /* Users.xcassets */, 116 | ); 117 | name = UsersViewController; 118 | sourceTree = ""; 119 | }; 120 | B57793EC1D78194900F92D7E /* UserTableCellView */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | B57793F11D7819C900F92D7E /* AHCUserTableCellView.xib */, 124 | B57793ED1D78197200F92D7E /* AHCUserTableCellView.h */, 125 | B57793F01D7819A800F92D7E /* AHCUserTableCellView+Private.h */, 126 | B57793EE1D78197200F92D7E /* AHCUserTableCellView.m */, 127 | ); 128 | name = UserTableCellView; 129 | sourceTree = ""; 130 | }; 131 | B57793F41D781C6F00F92D7E /* User */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | B57793F51D781C9500F92D7E /* AHCUser.h */, 135 | B57793F81D781CAB00F92D7E /* AHCUser+Private.h */, 136 | B57793F61D781C9500F92D7E /* AHCUser.m */, 137 | ); 138 | name = User; 139 | sourceTree = ""; 140 | }; 141 | B57793FD1D7834F200F92D7E /* MessagesViewController */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | B57794061D783DED00F92D7E /* MessageTableCellView */, 145 | B57794021D78360D00F92D7E /* AHCMessagesView.xib */, 146 | B57793FE1D78358900F92D7E /* AHCMessagesViewController.h */, 147 | B57794011D7835E600F92D7E /* AHCMessagesViewController+Private.h */, 148 | B57793FF1D78358900F92D7E /* AHCMessagesViewController.m */, 149 | B57794041D783A8400F92D7E /* Messages.plist */, 150 | ); 151 | name = MessagesViewController; 152 | sourceTree = ""; 153 | }; 154 | B57794061D783DED00F92D7E /* MessageTableCellView */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | B577940B1D783E6500F92D7E /* AHCMessageTableCellView.xib */, 158 | B57794071D783E1400F92D7E /* AHCMessageTableCellView.h */, 159 | B577940A1D783E2F00F92D7E /* AHCMessageTableCellView+Private.h */, 160 | B57794081D783E1400F92D7E /* AHCMessageTableCellView.m */, 161 | ); 162 | name = MessageTableCellView; 163 | sourceTree = ""; 164 | }; 165 | B5B633011AA1DF4200BBF084 = { 166 | isa = PBXGroup; 167 | children = ( 168 | B5B633081AA1DF6F00BBF084 /* KSPAutomaticHeightCalculationTableCellView */, 169 | B5B6330F1AA1DFAD00BBF084 /* Resources */, 170 | B57793D51D78129500F92D7E /* Sample */, 171 | B5CD03551BCBAC0C0072878A /* Products */, 172 | ); 173 | sourceTree = ""; 174 | }; 175 | B5B633081AA1DF6F00BBF084 /* KSPAutomaticHeightCalculationTableCellView */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | B5B633091AA1DF9B00BBF084 /* KSPAutomaticHeightCalculationTableCellView.h */, 179 | B5B6330C1AA1DF9B00BBF084 /* KSPAutomaticHeightCalculationTableCellView+Private.h */, 180 | B5B6330A1AA1DF9B00BBF084 /* KSPAutomaticHeightCalculationTableCellView.m */, 181 | ); 182 | name = KSPAutomaticHeightCalculationTableCellView; 183 | sourceTree = ""; 184 | }; 185 | B5B6330F1AA1DFAD00BBF084 /* Resources */ = { 186 | isa = PBXGroup; 187 | children = ( 188 | B5B6330B1AA1DF9B00BBF084 /* KSPAutomaticHeightCalculationTableCellView.podspec */, 189 | B5B6330E1AA1DF9B00BBF084 /* README.md */, 190 | B5B6330D1AA1DF9B00BBF084 /* LICENSE.md */, 191 | ); 192 | name = Resources; 193 | sourceTree = ""; 194 | }; 195 | B5CD03551BCBAC0C0072878A /* Products */ = { 196 | isa = PBXGroup; 197 | children = ( 198 | B5CD03541BCBAC0C0072878A /* libKSPAutomaticHeightCalculationTableCellView.dylib */, 199 | B57793C41D78112700F92D7E /* Sample.app */, 200 | ); 201 | name = Products; 202 | sourceTree = ""; 203 | }; 204 | /* End PBXGroup section */ 205 | 206 | /* Begin PBXHeadersBuildPhase section */ 207 | B5CD03521BCBAC0C0072878A /* Headers */ = { 208 | isa = PBXHeadersBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | B5CD035F1BCBB0B00072878A /* KSPAutomaticHeightCalculationTableCellView.h in Headers */, 212 | B5CD03601BCBB1430072878A /* KSPAutomaticHeightCalculationTableCellView+Private.h in Headers */, 213 | ); 214 | runOnlyForDeploymentPostprocessing = 0; 215 | }; 216 | /* End PBXHeadersBuildPhase section */ 217 | 218 | /* Begin PBXNativeTarget section */ 219 | B57793C31D78112700F92D7E /* Sample */ = { 220 | isa = PBXNativeTarget; 221 | buildConfigurationList = B57793D41D78112800F92D7E /* Build configuration list for PBXNativeTarget "Sample" */; 222 | buildPhases = ( 223 | B57793C01D78112700F92D7E /* Sources */, 224 | B57793C11D78112700F92D7E /* Frameworks */, 225 | B57793C21D78112700F92D7E /* Resources */, 226 | ); 227 | buildRules = ( 228 | ); 229 | dependencies = ( 230 | ); 231 | name = Sample; 232 | productName = Sample; 233 | productReference = B57793C41D78112700F92D7E /* Sample.app */; 234 | productType = "com.apple.product-type.application"; 235 | }; 236 | B5CD03531BCBAC0C0072878A /* KSPAutomaticHeightCalculationTableCellView */ = { 237 | isa = PBXNativeTarget; 238 | buildConfigurationList = B5CD035B1BCBAC0C0072878A /* Build configuration list for PBXNativeTarget "KSPAutomaticHeightCalculationTableCellView" */; 239 | buildPhases = ( 240 | B5CD03501BCBAC0C0072878A /* Sources */, 241 | B5CD03511BCBAC0C0072878A /* Frameworks */, 242 | B5CD03521BCBAC0C0072878A /* Headers */, 243 | ); 244 | buildRules = ( 245 | ); 246 | dependencies = ( 247 | ); 248 | name = KSPAutomaticHeightCalculationTableCellView; 249 | productName = KSPAutomaticHeightCalculationTableCellView; 250 | productReference = B5CD03541BCBAC0C0072878A /* libKSPAutomaticHeightCalculationTableCellView.dylib */; 251 | productType = "com.apple.product-type.library.dynamic"; 252 | }; 253 | /* End PBXNativeTarget section */ 254 | 255 | /* Begin PBXProject section */ 256 | B5B633021AA1DF4200BBF084 /* Project object */ = { 257 | isa = PBXProject; 258 | attributes = { 259 | CLASSPREFIX = KSP; 260 | LastUpgradeCheck = 0700; 261 | ORGANIZATIONNAME = "Konstantin Pavlikhin"; 262 | TargetAttributes = { 263 | B57793C31D78112700F92D7E = { 264 | CreatedOnToolsVersion = 7.3.1; 265 | }; 266 | B5CD03531BCBAC0C0072878A = { 267 | CreatedOnToolsVersion = 7.0.1; 268 | }; 269 | }; 270 | }; 271 | buildConfigurationList = B5B633051AA1DF4200BBF084 /* Build configuration list for PBXProject "KSPAutomaticHeightCalculationTableCellView" */; 272 | compatibilityVersion = "Xcode 3.2"; 273 | developmentRegion = English; 274 | hasScannedForEncodings = 0; 275 | knownRegions = ( 276 | en, 277 | Base, 278 | ); 279 | mainGroup = B5B633011AA1DF4200BBF084; 280 | productRefGroup = B5CD03551BCBAC0C0072878A /* Products */; 281 | projectDirPath = ""; 282 | projectRoot = ""; 283 | targets = ( 284 | B5CD03531BCBAC0C0072878A /* KSPAutomaticHeightCalculationTableCellView */, 285 | B57793C31D78112700F92D7E /* Sample */, 286 | ); 287 | }; 288 | /* End PBXProject section */ 289 | 290 | /* Begin PBXResourcesBuildPhase section */ 291 | B57793C21D78112700F92D7E /* Resources */ = { 292 | isa = PBXResourcesBuildPhase; 293 | buildActionMask = 2147483647; 294 | files = ( 295 | B57794051D783A8400F92D7E /* Messages.plist in Resources */, 296 | B577940C1D783E6500F92D7E /* AHCMessageTableCellView.xib in Resources */, 297 | B57794031D78360D00F92D7E /* AHCMessagesView.xib in Resources */, 298 | B57793DF1D7812EA00F92D7E /* Assets.xcassets in Resources */, 299 | B57793EB1D78155500F92D7E /* AHCUsersView.xib in Resources */, 300 | B57793E21D7812F300F92D7E /* MainMenu.xib in Resources */, 301 | B57793FA1D781FA000F92D7E /* Users.plist in Resources */, 302 | B57793FC1D78229F00F92D7E /* Users.xcassets in Resources */, 303 | B57793F21D7819C900F92D7E /* AHCUserTableCellView.xib in Resources */, 304 | ); 305 | runOnlyForDeploymentPostprocessing = 0; 306 | }; 307 | /* End PBXResourcesBuildPhase section */ 308 | 309 | /* Begin PBXSourcesBuildPhase section */ 310 | B57793C01D78112700F92D7E /* Sources */ = { 311 | isa = PBXSourcesBuildPhase; 312 | buildActionMask = 2147483647; 313 | files = ( 314 | B57793DD1D7812CB00F92D7E /* main.m in Sources */, 315 | B57793E71D7814F200F92D7E /* AHCUsersViewController.m in Sources */, 316 | B57793DC1D7812CB00F92D7E /* AppDelegate.m in Sources */, 317 | B57794001D78358900F92D7E /* AHCMessagesViewController.m in Sources */, 318 | B57793F71D781C9500F92D7E /* AHCUser.m in Sources */, 319 | B57793EF1D78197200F92D7E /* AHCUserTableCellView.m in Sources */, 320 | B57794091D783E1400F92D7E /* AHCMessageTableCellView.m in Sources */, 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | }; 324 | B5CD03501BCBAC0C0072878A /* Sources */ = { 325 | isa = PBXSourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | B5CD035E1BCBAC210072878A /* KSPAutomaticHeightCalculationTableCellView.m in Sources */, 329 | ); 330 | runOnlyForDeploymentPostprocessing = 0; 331 | }; 332 | /* End PBXSourcesBuildPhase section */ 333 | 334 | /* Begin PBXVariantGroup section */ 335 | B57793E01D7812F300F92D7E /* MainMenu.xib */ = { 336 | isa = PBXVariantGroup; 337 | children = ( 338 | B57793E11D7812F300F92D7E /* Base */, 339 | ); 340 | name = MainMenu.xib; 341 | sourceTree = ""; 342 | }; 343 | /* End PBXVariantGroup section */ 344 | 345 | /* Begin XCBuildConfiguration section */ 346 | B57793D21D78112800F92D7E /* Debug */ = { 347 | isa = XCBuildConfiguration; 348 | buildSettings = { 349 | ALWAYS_SEARCH_USER_PATHS = NO; 350 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 351 | CLANG_ANALYZER_NONNULL = YES; 352 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 353 | CLANG_CXX_LIBRARY = "libc++"; 354 | CLANG_ENABLE_MODULES = YES; 355 | CLANG_ENABLE_OBJC_ARC = YES; 356 | CLANG_WARN_BOOL_CONVERSION = YES; 357 | CLANG_WARN_CONSTANT_CONVERSION = YES; 358 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 359 | CLANG_WARN_EMPTY_BODY = YES; 360 | CLANG_WARN_ENUM_CONVERSION = YES; 361 | CLANG_WARN_INT_CONVERSION = YES; 362 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 363 | CLANG_WARN_UNREACHABLE_CODE = YES; 364 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 365 | CODE_SIGN_IDENTITY = "-"; 366 | COMBINE_HIDPI_IMAGES = YES; 367 | COPY_PHASE_STRIP = NO; 368 | DEBUG_INFORMATION_FORMAT = dwarf; 369 | ENABLE_STRICT_OBJC_MSGSEND = YES; 370 | GCC_C_LANGUAGE_STANDARD = gnu99; 371 | GCC_DYNAMIC_NO_PIC = NO; 372 | GCC_NO_COMMON_BLOCKS = YES; 373 | GCC_OPTIMIZATION_LEVEL = 0; 374 | GCC_PREPROCESSOR_DEFINITIONS = ( 375 | "DEBUG=1", 376 | "$(inherited)", 377 | ); 378 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 379 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 380 | GCC_WARN_UNDECLARED_SELECTOR = YES; 381 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 382 | GCC_WARN_UNUSED_FUNCTION = YES; 383 | GCC_WARN_UNUSED_VARIABLE = YES; 384 | INFOPLIST_FILE = Sample/Resources/Info.plist; 385 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 386 | MACOSX_DEPLOYMENT_TARGET = 10.11; 387 | MTL_ENABLE_DEBUG_INFO = YES; 388 | PRODUCT_BUNDLE_IDENTIFIER = com.konstantinpavlikhin.KSPAutomaticHeightCalculationTableCellViewSample; 389 | PRODUCT_NAME = "$(TARGET_NAME)"; 390 | SDKROOT = macosx; 391 | }; 392 | name = Debug; 393 | }; 394 | B57793D31D78112800F92D7E /* Release */ = { 395 | isa = XCBuildConfiguration; 396 | buildSettings = { 397 | ALWAYS_SEARCH_USER_PATHS = NO; 398 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 399 | CLANG_ANALYZER_NONNULL = YES; 400 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 401 | CLANG_CXX_LIBRARY = "libc++"; 402 | CLANG_ENABLE_MODULES = YES; 403 | CLANG_ENABLE_OBJC_ARC = YES; 404 | CLANG_WARN_BOOL_CONVERSION = YES; 405 | CLANG_WARN_CONSTANT_CONVERSION = YES; 406 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 407 | CLANG_WARN_EMPTY_BODY = YES; 408 | CLANG_WARN_ENUM_CONVERSION = YES; 409 | CLANG_WARN_INT_CONVERSION = YES; 410 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 411 | CLANG_WARN_UNREACHABLE_CODE = YES; 412 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 413 | CODE_SIGN_IDENTITY = "-"; 414 | COMBINE_HIDPI_IMAGES = YES; 415 | COPY_PHASE_STRIP = NO; 416 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 417 | ENABLE_NS_ASSERTIONS = NO; 418 | ENABLE_STRICT_OBJC_MSGSEND = YES; 419 | GCC_C_LANGUAGE_STANDARD = gnu99; 420 | GCC_NO_COMMON_BLOCKS = YES; 421 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 422 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 423 | GCC_WARN_UNDECLARED_SELECTOR = YES; 424 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 425 | GCC_WARN_UNUSED_FUNCTION = YES; 426 | GCC_WARN_UNUSED_VARIABLE = YES; 427 | INFOPLIST_FILE = Sample/Resources/Info.plist; 428 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 429 | MACOSX_DEPLOYMENT_TARGET = 10.11; 430 | MTL_ENABLE_DEBUG_INFO = NO; 431 | PRODUCT_BUNDLE_IDENTIFIER = com.konstantinpavlikhin.KSPAutomaticHeightCalculationTableCellViewSample; 432 | PRODUCT_NAME = "$(TARGET_NAME)"; 433 | SDKROOT = macosx; 434 | }; 435 | name = Release; 436 | }; 437 | B5B633061AA1DF4200BBF084 /* Debug */ = { 438 | isa = XCBuildConfiguration; 439 | buildSettings = { 440 | ENABLE_TESTABILITY = YES; 441 | ONLY_ACTIVE_ARCH = YES; 442 | }; 443 | name = Debug; 444 | }; 445 | B5B633071AA1DF4200BBF084 /* Release */ = { 446 | isa = XCBuildConfiguration; 447 | buildSettings = { 448 | }; 449 | name = Release; 450 | }; 451 | B5CD035C1BCBAC0C0072878A /* Debug */ = { 452 | isa = XCBuildConfiguration; 453 | buildSettings = { 454 | ALWAYS_SEARCH_USER_PATHS = NO; 455 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 456 | CLANG_CXX_LIBRARY = "libc++"; 457 | CLANG_ENABLE_MODULES = YES; 458 | CLANG_ENABLE_OBJC_ARC = YES; 459 | CLANG_WARN_BOOL_CONVERSION = YES; 460 | CLANG_WARN_CONSTANT_CONVERSION = YES; 461 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 462 | CLANG_WARN_EMPTY_BODY = YES; 463 | CLANG_WARN_ENUM_CONVERSION = YES; 464 | CLANG_WARN_INT_CONVERSION = YES; 465 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 466 | CLANG_WARN_UNREACHABLE_CODE = YES; 467 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 468 | COPY_PHASE_STRIP = NO; 469 | DEBUG_INFORMATION_FORMAT = dwarf; 470 | DYLIB_COMPATIBILITY_VERSION = 1; 471 | DYLIB_CURRENT_VERSION = 1; 472 | ENABLE_STRICT_OBJC_MSGSEND = YES; 473 | EXECUTABLE_PREFIX = lib; 474 | GCC_C_LANGUAGE_STANDARD = gnu99; 475 | GCC_DYNAMIC_NO_PIC = NO; 476 | GCC_NO_COMMON_BLOCKS = YES; 477 | GCC_OPTIMIZATION_LEVEL = 0; 478 | GCC_PREPROCESSOR_DEFINITIONS = ( 479 | "DEBUG=1", 480 | "$(inherited)", 481 | ); 482 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 483 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 484 | GCC_WARN_UNDECLARED_SELECTOR = YES; 485 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 486 | GCC_WARN_UNUSED_FUNCTION = YES; 487 | GCC_WARN_UNUSED_VARIABLE = YES; 488 | MACOSX_DEPLOYMENT_TARGET = 10.11; 489 | MTL_ENABLE_DEBUG_INFO = YES; 490 | PRODUCT_NAME = "$(TARGET_NAME)"; 491 | SDKROOT = macosx; 492 | }; 493 | name = Debug; 494 | }; 495 | B5CD035D1BCBAC0C0072878A /* Release */ = { 496 | isa = XCBuildConfiguration; 497 | buildSettings = { 498 | ALWAYS_SEARCH_USER_PATHS = NO; 499 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 500 | CLANG_CXX_LIBRARY = "libc++"; 501 | CLANG_ENABLE_MODULES = YES; 502 | CLANG_ENABLE_OBJC_ARC = YES; 503 | CLANG_WARN_BOOL_CONVERSION = YES; 504 | CLANG_WARN_CONSTANT_CONVERSION = YES; 505 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 506 | CLANG_WARN_EMPTY_BODY = YES; 507 | CLANG_WARN_ENUM_CONVERSION = YES; 508 | CLANG_WARN_INT_CONVERSION = YES; 509 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 510 | CLANG_WARN_UNREACHABLE_CODE = YES; 511 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 512 | COPY_PHASE_STRIP = NO; 513 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 514 | DYLIB_COMPATIBILITY_VERSION = 1; 515 | DYLIB_CURRENT_VERSION = 1; 516 | ENABLE_NS_ASSERTIONS = NO; 517 | ENABLE_STRICT_OBJC_MSGSEND = YES; 518 | EXECUTABLE_PREFIX = lib; 519 | GCC_C_LANGUAGE_STANDARD = gnu99; 520 | GCC_NO_COMMON_BLOCKS = YES; 521 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 522 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 523 | GCC_WARN_UNDECLARED_SELECTOR = YES; 524 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 525 | GCC_WARN_UNUSED_FUNCTION = YES; 526 | GCC_WARN_UNUSED_VARIABLE = YES; 527 | MACOSX_DEPLOYMENT_TARGET = 10.11; 528 | MTL_ENABLE_DEBUG_INFO = NO; 529 | PRODUCT_NAME = "$(TARGET_NAME)"; 530 | SDKROOT = macosx; 531 | }; 532 | name = Release; 533 | }; 534 | /* End XCBuildConfiguration section */ 535 | 536 | /* Begin XCConfigurationList section */ 537 | B57793D41D78112800F92D7E /* Build configuration list for PBXNativeTarget "Sample" */ = { 538 | isa = XCConfigurationList; 539 | buildConfigurations = ( 540 | B57793D21D78112800F92D7E /* Debug */, 541 | B57793D31D78112800F92D7E /* Release */, 542 | ); 543 | defaultConfigurationIsVisible = 0; 544 | defaultConfigurationName = Release; 545 | }; 546 | B5B633051AA1DF4200BBF084 /* Build configuration list for PBXProject "KSPAutomaticHeightCalculationTableCellView" */ = { 547 | isa = XCConfigurationList; 548 | buildConfigurations = ( 549 | B5B633061AA1DF4200BBF084 /* Debug */, 550 | B5B633071AA1DF4200BBF084 /* Release */, 551 | ); 552 | defaultConfigurationIsVisible = 0; 553 | defaultConfigurationName = Release; 554 | }; 555 | B5CD035B1BCBAC0C0072878A /* Build configuration list for PBXNativeTarget "KSPAutomaticHeightCalculationTableCellView" */ = { 556 | isa = XCConfigurationList; 557 | buildConfigurations = ( 558 | B5CD035C1BCBAC0C0072878A /* Debug */, 559 | B5CD035D1BCBAC0C0072878A /* Release */, 560 | ); 561 | defaultConfigurationIsVisible = 0; 562 | defaultConfigurationName = Release; 563 | }; 564 | /* End XCConfigurationList section */ 565 | }; 566 | rootObject = B5B633021AA1DF4200BBF084 /* Project object */; 567 | } 568 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | **Copyright © 2016, Konstantin Pavlikhin.** 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## KSPAutomaticHeightCalculationTableCellView 2 | 3 | [![Version](https://img.shields.io/cocoapods/v/KSPAutomaticHeightCalculationTableCellView.svg)](https://cocoapods.org/pods/KSPAutomaticHeightCalculationTableCellView) 4 | [![Platform](https://img.shields.io/cocoapods/p/KSPAutomaticHeightCalculationTableCellView.svg)](https://cocoapods.org/pods/KSPAutomaticHeightCalculationTableCellView) 5 | [![License](https://img.shields.io/cocoapods/l/KSPAutomaticHeightCalculationTableCellView.svg)](https://cocoapods.org/pods/KSPAutomaticHeightCalculationTableCellView) 6 | 7 | A useful superclass for a custom view-based `NSTableView`’s cell. 8 | 9 | ## Sample Application 10 | 11 | There is a simple application that demonstrates `KSPAutomaticHeightCalculationTableCellView` in action. The app shows a single window with an embedded split view. The left pane has a fixed-height cells (`AHCUserTableCellView`) that represent some fictional users. The right pane has cells (`AHCMessageTableCellView`) whose heights depend both on their textual content and a column width. When window is resized the table view on the right is notified to re-query the row heights from the delegate. 12 | 13 | ![](Sample/Screenshot.png) 14 | 15 | ## How To Use 16 | 17 | #### Your custom cell class should inherit from `KSPAutomaticHeightCalculationTableCellView` 18 | 19 | This is how it used to look in Objective-C: 20 | 21 | ```objective-c 22 | #import 23 | 24 | @interface MyLovelyCell : KSPAutomaticHeightCalculationTableCellView 25 | … 26 | @end 27 | ``` 28 | 29 | #### Put your cell into a separate XIB and let the `KSPAutomaticHeightCalculationTableCellView` know how to find it at runtime 30 | 31 | It is generally a good idea to put your cell into a separate XIB, but usage of a `KSPAutomaticHeightCalculationTableCellView` makes this mandatory. 32 | 33 | By default `KSPAutomaticHeightCalculationTableCellView` will look for a nib file named exactly like your cell's subclass in a main bundle. 34 | 35 | That is, if you call your cell class `MyLovelyCell` you have to name your XIB `MyLovelyCell.xib`. This xib should contain one and only one root view of MyLovelyCell class. You still can have an arbitrary number of other objects in a XIB, though. 36 | 37 | You can customize the behaviour by overriding the following class methods: 38 | 39 | ```objective-c 40 | + (nonnull NSString*) correspondingNibName 41 | { 42 | return @"SomethingDifferent"; 43 | } 44 | ``` 45 | 46 | ```objective-c 47 | + (nonnull NSBundle*) correspondingBundle 48 | { 49 | return [NSBundle bundle...]; 50 | } 51 | ``` 52 | 53 | #### Decide whether your custom table cell should have a variable height 54 | 55 | **Cell has a variable height** == **Cell's height depends on a represented object value** `OR` **cell's height depends on cell's width**. 56 | 57 | By default, `KSPAutomaticHeightCalculationTableCellView` assumes that your cell has a variable height, since this is the basic reason to use the class in your project at all. 58 | 59 | Override `+hasFixedHeight` and return `YES` if your cell's height is really fixed. 60 | 61 | ```objective-c 62 | + (BOOL) hasFixedHeight 63 | { 64 | return YES; 65 | } 66 | ``` 67 | 68 | In this case `KSPAutomaticHeightCalculationTableCellView` will cache the height after it will be calculated for the first time. Subsequent calls to `+heightWithRepresentedObject:width:` will return the stored value. 69 | 70 | #### Layout your cell via Auto Layout 71 | 72 | This step is also mandatory. `KSPAutomaticHeightCalculationTableCellView` only functions in Auto Layout-enabled mode. There is no point of using the class if you perform manual frame computations. 73 | 74 | **Attention, this part is really important**: 75 | After you add layout constraints, the height of your cell __should be unambiguous__! This means, height have to be constraint either directly (via explicit height constraint, which will render `KSPAutomaticHeightCalculationTableCellView` usage pretty pointless, since you already know the height value) or in a derived-fashion (in which height of a cell somehow depends on a geometry of its subviews, and the geometry, in its turn, depends on content). 76 | 77 | Remember it, cause if you leave your cell view's height ambigous you will end up with a table view rows having a zero height. 78 | 79 | #### Implement a `NSTableViewDelegate` method `-tableView:heightOfRow:` 80 | 81 | ```objective-c 82 | - (CGFloat) tableView: (NSTableView*) tableView heightOfRow: (NSInteger) row 83 | { 84 | // Get the width of a column in which the cell should reside. 85 | CGFloat columnWidth = [tableView tableColumnWithIdentifier: @“MainColumn”].width; 86 | 87 | // Let the KSPAutomaticHeightCalculationTableCellView to calculate the preffered cell height for you. 88 | return [MyLovelyCell heightWithRepresentedObject: # width: columnWidth]; 89 | } 90 | ``` 91 | 92 | At this point `KSPAutomaticHeightCalculationTableCellView` will create a prototype cell instance, set its `objectValue` property to the passed value, constrain its width to the `columnWidth` and calculate the minimum required height. 93 | 94 | #### Make sure you don't make unnecessary work in your table cell view prototype 95 | 96 | When `KSPAutomaticHeightCalculationTableCellView` instantiates a cell for measurement purposes it sets its boolean `prototype` property to `YES`. If you happen to do some heavy-lifting in your table cell view subclass, for example, doing expensive calculations in response to an `objectValue` change, please refrain from doing so if the calculation result doesn't affect the layout. 97 | 98 | ```objective-c 99 | if(!self.prototype) 100 | { 101 | // Do some fancy visual effects pre-calculation (image caching, data detection and so on...). 102 | } 103 | else 104 | { 105 | // This cell is a prototype that is being reused for a row height calculation (possibly hundreds times per second). 106 | } 107 | ``` 108 | 109 | That's it! 110 | -------------------------------------------------------------------------------- /Sample/Resources/AHCMessageTableCellView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Sample/Resources/AHCMessagesView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /Sample/Resources/AHCUserTableCellView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /Sample/Resources/AHCUsersView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /Sample/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Sample/Resources/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | Default 542 | 543 | 544 | 545 | 546 | 547 | 548 | Left to Right 549 | 550 | 551 | 552 | 553 | 554 | 555 | Right to Left 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | Default 567 | 568 | 569 | 570 | 571 | 572 | 573 | Left to Right 574 | 575 | 576 | 577 | 578 | 579 | 580 | Right to Left 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | -------------------------------------------------------------------------------- /Sample/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Sample/Resources/Messages.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools. 6 | A computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are, in short, a perfect match. 7 | A good programmer is someone who always looks both ways before crossing a one-way street. 8 | A language that doesn't have everything is actually easier to program in than some that do. 9 | Any man can make mistakes, but only an idiot persists in his error. 10 | Are you quite sure that all those bells and whistles, all those wonderful facilities of your so called powerful programming languages, belong to the solution set rather than the problem set? 11 | Art is never finished, only abandoned. 12 | Assumption is the mother of all fuckups. 13 | Beauty is the ultimate defense against complexity. 14 | C is a razor-sharp tool, with which one can create an elegant and efficient program or a bloody mess. 15 | Compatibility means deliberately repeating other people's mistakes. 16 | Computers are good at following instructions, but not at reading your mind. 17 | Computers are useless. They can only give you answers. 18 | Controlling complexity is the essence of computer programming. 19 | Corporation, n. An ingenious device for obtaining individual profit without individual responsibility. 20 | Creativity is just connecting things. When you ask creative people how they did something, they feel a little guilty because they didn't really do it, they just saw something. It seemed obvious to them after a while. That's because they were able to connect experiences they've had and synthesize new things. And the reason they were able to do that was that they've had more experiences or they have thought more about their experiences than other people. 21 | Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. 22 | Deleted code is debugged code. 23 | Elegance is not a dispensable luxury but a quality that decides between success and failure. 24 | Engineering is the art of doing with one dollar what any damn fool can do with two. 25 | Every being in the universe knows right from wrong. 26 | Give me six hours to chop down a tree and I will spend the first four sharpening the axe. 27 | Givern enough thrust even a brick will fly. 28 | God is real, unless explicitly declared as integer. 29 | Great software, likewise, requires a fanatical devotion to beauty. If you look inside good software, you find that parts no one is ever supposed to see are beautiful too. I'm not claiming I write great software, but I know that when it comes to code I behave in a way that would make me eligible for prescription drugs if I approached everyday life the same way. It drives me crazy to see code that's badly indented, or that uses ugly variable names. 30 | Have no fear of perfection — you'll never reach it. 31 | I cannot give you the formula for success, but I can give you the formula for failure: which is: try to please everybody. 32 | I contend that we are both atheists. I just believe in one fewer god than you do. When you understand why you dismiss all the other possible gods, you will understand why I dismiss yours. 33 | I hear and I forget. I see and I remember. I do and I understand. 34 | If I had more time, I would have written a shorter letter. 35 | If we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent". 36 | If you can't explain it simply, you don't understand it well enough. 37 | If you cannot grok the overall structure of a program while taking a shower, e.g., with no external memory aids, you are not ready to code it. 38 | If you don’t fail at least 90 percent of the time, you’re not aiming high enough. 39 | If you think C++ is not overly complicated, just what is a protected abstract virtual base pure virtual private destructor and when was the last time you needed one? 40 | If you want me to give you a two-hour presentation, I am ready today. If you want only a five-minute speech, it will take me two weeks to prepare. 41 | If you want to make an apple pie from scratch, you must first create the universe. 42 | In all affairs it's a healthy thing now and then to hang a question mark on the things you have long taken for granted. 43 | In the modern world the stupid are cocksure while the intelligent are full of doubt. 44 | Inspiration exists, but it has to find you working. 45 | Isn't it enough to see that a garden is beautiful without having to believe that there are fairies at the bottom of it too? 46 | It is my ambition to say in ten sentences what others say in a whole book. 47 | It's very easy to be different, but very difficult to be better. 48 | Law 1: Every program can be optimized to be smaller. Law 2: There's always one more bug. Corollary: Every program can be reduced to a one-line bug. 49 | Life is like riding a bicycle. To keep your balance, you must keep moving. 50 | Measuring programming progress by lines of code is like measuring aircraft building progress by weight. 51 | Men never do evil so completely and cheerfully as when they do it from a religious conviction. 52 | More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason — including blind stupidity. 53 | Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves. 54 | My tastes are simple: I am easily satisfied with the best. 55 | No masterpiece was ever created by a lazy artist. 56 | Nothing is more permanent than a temporary solution. 57 | Object-oriented design is the roman numerals of computing. 58 | One Page Principle: A specification that will not fit on one page of 8.5x11 inch paper cannot be understood. 59 | One of my most productive days was throwing away 1000 lines of code. 60 | One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs. 61 | People love chopping wood. In this activity one immediately sees results. 62 | People who deal with bits should expect to get bitten. 63 | Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. 64 | Perl — The only language that looks the same before and after RSA encryption. 65 | Programming graphics in X is like finding the square root of PI using Roman numerals. 66 | Programming is a desperate losing battle against the unconquerable complexity of code. 67 | Simplicity is a great virtue but it requires hard work to achieve it and education to appreciate it. And to make matters worse: complexity sells better. 68 | Simplicity is prerequisite for reliability. 69 | Simplicity is the ultimate sophistication. 70 | So far as I can remember, there is not one word in the Gospels in praise of intelligence. 71 | Software and cathedrals are much the same. First we build them, then we pray. 72 | Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. 73 | Syntactic sugar causes cancer of the semicolon. 74 | That's the thing about people who think they hate computers. What they really hate is lousy programmers. 75 | The ability to simplify means to eliminate the unnecessary so that the necessary may speak. 76 | The best way to predict the future is to invent it. 77 | The computing scientist's main challenge is not to get confused by the complexities of his own making. 78 | The important thing is not to stop questioning. Curiosity has its own reason for existing. One cannot help but be in awe when he contemplates the mysteries of eternity, of life, of the marvelous structure of reality. It is enough if one tries merely to comprehend a little of this mystery every day. Never lose a holy curiosity. 79 | The major cause [of the software crisis] is that the machines have become several orders of magnitude more powerful! To put it quite bluntly: as long as there were no machines, programming was no problem at all; when we had a few weak computers, programming became a mild problem, and now we have gigantic computers, programming has become an equally gigantic problem. In this sense the electronic industry has not solved a single problem, it has only created them, it has created the problem of using its products. 80 | The most amazing achievement of the computer software industry is its continuing cancellation of the steady and staggering gains made by the computer hardware industry. 81 | The most effective debugging tool is still careful thought, coupled with judiciously placed print statements. 82 | The only way for errors to occur in a program is by being put there by the author. No other mechanisms are known. Programs can't acquire bugs by sitting around with other buggy programs. 83 | The question of whether computers can think is like the question of whether submarines can swim. 84 | The road to hell is paved with good intentions. 85 | Those who put blinders on their eyes should remember that the set also includes bridle and a whip. 86 | Too many people spend money they haven’t earned, to buy things they don’t want, to impress people they don’t like. 87 | We have persistant objects, they're called files. 88 | When the only tool you own is a hammer, every problem you encounter resembles a nail. 89 | When you're young, you look at television and think, There's a conspiracy. The networks have conspired to dumb us down. But when you get a little older, you realize that's not true. The networks are in business to give people exactly what they want. That's a far more depressing thought. Conspiracy is optimistic! You can shoot the bastards! We can have a revolution! But the networks are really in business to give people what they want. It's the truth. 90 | When you’re a carpenter making a beautiful chest of drawers, you’re not going to use a piece of plywood on the back, even though it faces the wall and nobody will ever see it. You’ll know it’s there, so you’re going to use a beautiful piece of wood on the back. For you to sleep well at night, the aesthetic, the quality, has to be carried all the way through. 91 | Why join the navy if you can be a pirate? 92 | Work expands so as to fill the time available for its completion. 93 | You know that I write slowly. This is chiefly because I am never satisfied until I have said as much as possible in a few words, and writing briefly takes far more time than writing at length. 94 | You probably know that arrogance, in computer science, is measured in nanodijkstras. 95 | You're bound to be unhappy if you optimize everything. 96 | 97 | 98 | -------------------------------------------------------------------------------- /Sample/Resources/Users.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | name 7 | Andrew Adams 8 | avatarName 9 | b197acb806bb016fbd90d1a0f6011c6cafb0a71c 10 | status 11 | 12 | 13 | 14 | 15 | name 16 | Steven Walters 17 | avatarName 18 | c08ddc798a249f1aaafff96bcf48ba5622e48bae 19 | status 20 | All your base are belong to us 21 | 22 | 23 | 24 | name 25 | Thomas Boyd 26 | avatarName 27 | 29c5f52c7fcfb870b4a22b4477fd61162b0c0813 28 | status 29 | Don't let me be misunderstood 30 | 31 | 32 | 33 | name 34 | Amy Garrett 35 | avatarName 36 | 6f368cf70844e68b8f68484fe037a13dbab4d719 37 | status 38 | Working from 7 to 11 39 | 40 | 41 | 42 | name 43 | Emma Webb 44 | avatarName 45 | 9e5403114811093818a8daa5d9a1f95edbaff465 46 | status 47 | Kittens are fuzzy 48 | 49 | 50 | 51 | name 52 | Harrison White 53 | avatarName 54 | fe989b5336a096c9f73a38c73b05f0c6822d553d 55 | status 56 | 57 | 58 | 59 | 60 | name 61 | Amber Bowman 62 | avatarName 63 | 9b90c3e22c9c859bf8ffa31ca016011d7944499c 64 | status 65 | Magic carpet ride! 66 | 67 | 68 | 69 | name 70 | Alex Scott 71 | avatarName 72 | 3a65d049905d2b7abb60f7e4a6195433b3485c64 73 | status 74 | Discovering Venice 75 | 76 | 77 | 78 | name 79 | Janis Howard 80 | avatarName 81 | eb67acf37daeecb670e5a2929f722dae0ef046ed 82 | status 83 | Summertime 84 | 85 | 86 | 87 | name 88 | Gerald Hopkins 89 | avatarName 90 | 079f2a7c99f9514e44fbff57468a051dddcda4ea 91 | status 92 | Jailbreak 93 | 94 | 95 | 96 | name 97 | Ella Anderson 98 | avatarName 99 | f732eac5da70e26d366cc1cde3674d721657a78e 100 | status 101 | Ramble On 102 | 103 | 104 | 105 | name 106 | Alice Smith 107 | avatarName 108 | 21bfc3a4ef1fdd04843c7ab3e369548873b2bb32 109 | status 110 | 111 | 112 | 113 | 114 | name 115 | Charlotte Harris 116 | avatarName 117 | 92b3949de0d021744ff38db72c1ea3c3b6e15552 118 | status 119 | 120 | 121 | 122 | 123 | name 124 | John Taylor 125 | avatarName 126 | 5f9654a329bfa919b0b3907efb54ece76b16328f 127 | status 128 | Live, love, travel 129 | 130 | 131 | 132 | name 133 | Elliot Walker 134 | avatarName 135 | d2dcdd803676fa25d2a0ab847dd78d25c4711f81 136 | status 137 | Free hugs! 138 | 139 | 140 | 141 | name 142 | Lilly Bell 143 | avatarName 144 | c3f7a2e83db7ee9ede31377dabf10c1745787653 145 | status 146 | 147 | 148 | 149 | 150 | name 151 | Daisy Campbell 152 | avatarName 153 | 22ca6c3b376c0db48ece8a330b3ececacee3202b 154 | status 155 | Available 156 | 157 | 158 | 159 | name 160 | Jasmine Brown 161 | avatarName 162 | dff85d5459b00c277b1f72f800d8ac4b389acffa 163 | status 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/079f2a7c99f9514e44fbff57468a051dddcda4ea.imageset/079f2a7c99f9514e44fbff57468a051dddcda4ea.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/079f2a7c99f9514e44fbff57468a051dddcda4ea.imageset/079f2a7c99f9514e44fbff57468a051dddcda4ea.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/079f2a7c99f9514e44fbff57468a051dddcda4ea.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "079f2a7c99f9514e44fbff57468a051dddcda4ea.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/21bfc3a4ef1fdd04843c7ab3e369548873b2bb32.imageset/21bfc3a4ef1fdd04843c7ab3e369548873b2bb32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/21bfc3a4ef1fdd04843c7ab3e369548873b2bb32.imageset/21bfc3a4ef1fdd04843c7ab3e369548873b2bb32.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/21bfc3a4ef1fdd04843c7ab3e369548873b2bb32.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "21bfc3a4ef1fdd04843c7ab3e369548873b2bb32.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/22ca6c3b376c0db48ece8a330b3ececacee3202b.imageset/22ca6c3b376c0db48ece8a330b3ececacee3202b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/22ca6c3b376c0db48ece8a330b3ececacee3202b.imageset/22ca6c3b376c0db48ece8a330b3ececacee3202b.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/22ca6c3b376c0db48ece8a330b3ececacee3202b.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "22ca6c3b376c0db48ece8a330b3ececacee3202b.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/29c5f52c7fcfb870b4a22b4477fd61162b0c0813.imageset/29c5f52c7fcfb870b4a22b4477fd61162b0c0813.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/29c5f52c7fcfb870b4a22b4477fd61162b0c0813.imageset/29c5f52c7fcfb870b4a22b4477fd61162b0c0813.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/29c5f52c7fcfb870b4a22b4477fd61162b0c0813.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "29c5f52c7fcfb870b4a22b4477fd61162b0c0813.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/3a65d049905d2b7abb60f7e4a6195433b3485c64.imageset/3a65d049905d2b7abb60f7e4a6195433b3485c64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/3a65d049905d2b7abb60f7e4a6195433b3485c64.imageset/3a65d049905d2b7abb60f7e4a6195433b3485c64.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/3a65d049905d2b7abb60f7e4a6195433b3485c64.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "3a65d049905d2b7abb60f7e4a6195433b3485c64.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/5f9654a329bfa919b0b3907efb54ece76b16328f.imageset/5f9654a329bfa919b0b3907efb54ece76b16328f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/5f9654a329bfa919b0b3907efb54ece76b16328f.imageset/5f9654a329bfa919b0b3907efb54ece76b16328f.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/5f9654a329bfa919b0b3907efb54ece76b16328f.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "5f9654a329bfa919b0b3907efb54ece76b16328f.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/6f368cf70844e68b8f68484fe037a13dbab4d719.imageset/6f368cf70844e68b8f68484fe037a13dbab4d719.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/6f368cf70844e68b8f68484fe037a13dbab4d719.imageset/6f368cf70844e68b8f68484fe037a13dbab4d719.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/6f368cf70844e68b8f68484fe037a13dbab4d719.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "6f368cf70844e68b8f68484fe037a13dbab4d719.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/92b3949de0d021744ff38db72c1ea3c3b6e15552.imageset/92b3949de0d021744ff38db72c1ea3c3b6e15552.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/92b3949de0d021744ff38db72c1ea3c3b6e15552.imageset/92b3949de0d021744ff38db72c1ea3c3b6e15552.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/92b3949de0d021744ff38db72c1ea3c3b6e15552.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "92b3949de0d021744ff38db72c1ea3c3b6e15552.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/9b90c3e22c9c859bf8ffa31ca016011d7944499c.imageset/9b90c3e22c9c859bf8ffa31ca016011d7944499c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/9b90c3e22c9c859bf8ffa31ca016011d7944499c.imageset/9b90c3e22c9c859bf8ffa31ca016011d7944499c.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/9b90c3e22c9c859bf8ffa31ca016011d7944499c.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "9b90c3e22c9c859bf8ffa31ca016011d7944499c.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/9e5403114811093818a8daa5d9a1f95edbaff465.imageset/9e5403114811093818a8daa5d9a1f95edbaff465.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/9e5403114811093818a8daa5d9a1f95edbaff465.imageset/9e5403114811093818a8daa5d9a1f95edbaff465.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/9e5403114811093818a8daa5d9a1f95edbaff465.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "9e5403114811093818a8daa5d9a1f95edbaff465.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/b197acb806bb016fbd90d1a0f6011c6cafb0a71c.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "b197acb806bb016fbd90d1a0f6011c6cafb0a71c.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/b197acb806bb016fbd90d1a0f6011c6cafb0a71c.imageset/b197acb806bb016fbd90d1a0f6011c6cafb0a71c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/b197acb806bb016fbd90d1a0f6011c6cafb0a71c.imageset/b197acb806bb016fbd90d1a0f6011c6cafb0a71c.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/c08ddc798a249f1aaafff96bcf48ba5622e48bae.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "c08ddc798a249f1aaafff96bcf48ba5622e48bae.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/c08ddc798a249f1aaafff96bcf48ba5622e48bae.imageset/c08ddc798a249f1aaafff96bcf48ba5622e48bae.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/c08ddc798a249f1aaafff96bcf48ba5622e48bae.imageset/c08ddc798a249f1aaafff96bcf48ba5622e48bae.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/c3f7a2e83db7ee9ede31377dabf10c1745787653.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "c3f7a2e83db7ee9ede31377dabf10c1745787653.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/c3f7a2e83db7ee9ede31377dabf10c1745787653.imageset/c3f7a2e83db7ee9ede31377dabf10c1745787653.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/c3f7a2e83db7ee9ede31377dabf10c1745787653.imageset/c3f7a2e83db7ee9ede31377dabf10c1745787653.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/d2dcdd803676fa25d2a0ab847dd78d25c4711f81.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "d2dcdd803676fa25d2a0ab847dd78d25c4711f81.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/d2dcdd803676fa25d2a0ab847dd78d25c4711f81.imageset/d2dcdd803676fa25d2a0ab847dd78d25c4711f81.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/d2dcdd803676fa25d2a0ab847dd78d25c4711f81.imageset/d2dcdd803676fa25d2a0ab847dd78d25c4711f81.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/dff85d5459b00c277b1f72f800d8ac4b389acffa.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "dff85d5459b00c277b1f72f800d8ac4b389acffa.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/dff85d5459b00c277b1f72f800d8ac4b389acffa.imageset/dff85d5459b00c277b1f72f800d8ac4b389acffa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/dff85d5459b00c277b1f72f800d8ac4b389acffa.imageset/dff85d5459b00c277b1f72f800d8ac4b389acffa.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/eb67acf37daeecb670e5a2929f722dae0ef046ed.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "eb67acf37daeecb670e5a2929f722dae0ef046ed.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/eb67acf37daeecb670e5a2929f722dae0ef046ed.imageset/eb67acf37daeecb670e5a2929f722dae0ef046ed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/eb67acf37daeecb670e5a2929f722dae0ef046ed.imageset/eb67acf37daeecb670e5a2929f722dae0ef046ed.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/f732eac5da70e26d366cc1cde3674d721657a78e.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "f732eac5da70e26d366cc1cde3674d721657a78e.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/f732eac5da70e26d366cc1cde3674d721657a78e.imageset/f732eac5da70e26d366cc1cde3674d721657a78e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/f732eac5da70e26d366cc1cde3674d721657a78e.imageset/f732eac5da70e26d366cc1cde3674d721657a78e.jpg -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/fe989b5336a096c9f73a38c73b05f0c6822d553d.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "fe989b5336a096c9f73a38c73b05f0c6822d553d.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Sample/Resources/Users.xcassets/fe989b5336a096c9f73a38c73b05f0c6822d553d.imageset/fe989b5336a096c9f73a38c73b05f0c6822d553d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Resources/Users.xcassets/fe989b5336a096c9f73a38c73b05f0c6822d553d.imageset/fe989b5336a096c9f73a38c73b05f0c6822d553d.jpg -------------------------------------------------------------------------------- /Sample/Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konstantinpavlikhin/KSPAutomaticHeightCalculationTableCellView/12ef5994ce3fa5502edb8782bd309a3e5e04a332/Sample/Screenshot.png -------------------------------------------------------------------------------- /Sample/Sources/AHCMessageTableCellView+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // AHCMessageTableCellView+Private.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "AHCMessageTableCellView.h" 10 | 11 | @interface AHCMessageTableCellView () 12 | 13 | @property(readwrite, strong, nonatomic) IBOutlet NSTextField* textLabel; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Sample/Sources/AHCMessageTableCellView.h: -------------------------------------------------------------------------------- 1 | // 2 | // AHCMessageTableCellView.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AHCMessageTableCellView : KSPAutomaticHeightCalculationTableCellView 12 | 13 | @property(readwrite, strong, atomic, nullable) NSString* objectValue; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Sample/Sources/AHCMessageTableCellView.m: -------------------------------------------------------------------------------- 1 | // 2 | // AHCMessageTableCellView.m 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "AHCMessageTableCellView+Private.h" 10 | 11 | // * * *. 12 | 13 | static void* ObjectValueKVOContext; 14 | 15 | // * * *. 16 | 17 | @implementation AHCMessageTableCellView 18 | 19 | @dynamic objectValue; 20 | 21 | #pragma mark - Cleanup 22 | 23 | - (void) dealloc 24 | { 25 | [self removeObserver: self forKeyPath: NSStringFromSelector(@selector(objectValue)) context: &ObjectValueKVOContext]; 26 | } 27 | 28 | #pragma mark - NSView Overrides 29 | 30 | - (void) layout 31 | { 32 | [super layout]; 33 | 34 | // * * *. 35 | 36 | {{ 37 | // NSTextField has issues with a text measurement, it underestimates height of a text for a given maximum width. 38 | const CGFloat correction = 4; 39 | 40 | self.textLabel.preferredMaxLayoutWidth = (self.textLabel.frame.size.width - correction); 41 | }} 42 | 43 | // * * *. 44 | 45 | [super layout]; 46 | } 47 | 48 | #pragma mark - 49 | 50 | - (void) awakeFromNib 51 | { 52 | [super awakeFromNib]; 53 | 54 | // * * *. 55 | 56 | [self addObserver: self forKeyPath: NSStringFromSelector(@selector(objectValue)) options: 0 context: &ObjectValueKVOContext]; 57 | } 58 | 59 | #pragma mark - Key-Value Observation 60 | 61 | - (void) observeValueForKeyPath: (NSString*) keyPath ofObject: (id) object change: (NSDictionary*) change context: (void*) context 62 | { 63 | if(context == &ObjectValueKVOContext) 64 | { 65 | // Text. 66 | self.textLabel.objectValue = self.objectValue; 67 | } 68 | else 69 | { 70 | [super observeValueForKeyPath: keyPath ofObject: object change: change context: context]; 71 | } 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Sample/Sources/AHCMessagesViewController+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // AHCMessagesViewController+Private.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "AHCMessagesViewController.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface AHCMessagesViewController () 14 | 15 | @property(readwrite, strong, nonatomic) IBOutlet NSTableView* tableView; 16 | 17 | @property(readwrite, strong, nonatomic) IBOutlet NSTableColumn* mainColumn; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Sample/Sources/AHCMessagesViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AHCMessagesViewController.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface AHCMessagesViewController : NSViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Sample/Sources/AHCMessagesViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AHCMessagesViewController.m 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "AHCMessagesViewController+Private.h" 10 | 11 | #import "AHCMessageTableCellView.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @implementation AHCMessagesViewController 16 | { 17 | NSArray* _messages; 18 | } 19 | 20 | #pragma mark - 21 | 22 | - (void) awakeFromNib 23 | { 24 | [super awakeFromNib]; 25 | 26 | // * * *. 27 | 28 | [self loadMessages]; 29 | 30 | [self registerCells]; 31 | 32 | // * * *. 33 | 34 | [self.tableView reloadData]; 35 | } 36 | 37 | #pragma mark - Private Methods 38 | 39 | - (void) loadMessages 40 | { 41 | NSURL* const URL = [[NSBundle mainBundle] URLForResource: @"Messages" withExtension: @"plist"]; 42 | 43 | NSData* const data = [NSData dataWithContentsOfURL: URL]; 44 | 45 | NSError* error; 46 | 47 | NSArray* const messagesOrNil = [NSPropertyListSerialization propertyListWithData: data options: NSPropertyListImmutable format: nil error: &error]; 48 | 49 | if(messagesOrNil) 50 | { 51 | _messages = messagesOrNil; 52 | } 53 | else 54 | { 55 | NSLog(@"%@", error); 56 | } 57 | } 58 | 59 | - (void) registerCells 60 | { 61 | NSString* const className = NSStringFromClass([AHCMessageTableCellView class]); 62 | 63 | [self.tableView registerNib: [[NSNib alloc] initWithNibNamed: className bundle: nil] forIdentifier: className]; 64 | } 65 | 66 | #pragma mark - NSTableViewDataSource Protocol Implementation 67 | 68 | - (NSInteger) numberOfRowsInTableView: (NSTableView*) tableView 69 | { 70 | return _messages.count; 71 | } 72 | 73 | - (nullable id) tableView: (NSTableView*) tableView objectValueForTableColumn: (nullable NSTableColumn*) tableColumn row: (NSInteger) row 74 | { 75 | return _messages[row]; 76 | } 77 | 78 | #pragma mark - NSTableViewDelegate Protocol Implementation 79 | 80 | - (nullable NSView*) tableView: (NSTableView*) tableView viewForTableColumn: (nullable NSTableColumn*) tableColumn row: (NSInteger) row 81 | { 82 | NSString* const className = NSStringFromClass([AHCMessageTableCellView class]); 83 | 84 | return [tableView makeViewWithIdentifier: className owner: nil]; 85 | } 86 | 87 | - (CGFloat) tableView: (NSTableView*) tableView heightOfRow: (NSInteger) row 88 | { 89 | return [AHCMessageTableCellView heightWithRepresentedObject: _messages[row] width: self.mainColumn.width]; 90 | } 91 | 92 | - (void) tableViewColumnDidResize: (NSNotification*) notification 93 | { 94 | if(notification.userInfo[@"NSTableColumn"] == self.mainColumn) 95 | { 96 | [NSAnimationContext runAnimationGroup: ^(NSAnimationContext* _Nonnull const context) 97 | { 98 | context.duration = 0; 99 | 100 | [self.tableView noteHeightOfRowsWithIndexesChanged: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, _messages.count)]]; 101 | } completionHandler: nil]; 102 | } 103 | } 104 | 105 | @end 106 | 107 | NS_ASSUME_NONNULL_END 108 | -------------------------------------------------------------------------------- /Sample/Sources/AHCUser+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // AHCUser+Private.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "AHCUser.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface AHCUser () 14 | 15 | @property(readwrite, strong, nonatomic) NSString* name; 16 | 17 | @property(readwrite, strong, nonatomic) NSImage* avatar; 18 | 19 | @property(readwrite, strong, nonatomic, nullable) NSString* status; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Sample/Sources/AHCUser.h: -------------------------------------------------------------------------------- 1 | // 2 | // AHCUser.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface AHCUser : NSObject 14 | 15 | - (instancetype) initWithName: (NSString*) name avatar: (NSImage*) avatar status: (nullable NSString*) statusOrNil NS_DESIGNATED_INITIALIZER; 16 | 17 | @property(readonly, strong, nonatomic) NSString* name; 18 | 19 | @property(readonly, strong, nonatomic) NSImage* avatar; 20 | 21 | @property(readonly, strong, nonatomic, nullable) NSString* status; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Sample/Sources/AHCUser.m: -------------------------------------------------------------------------------- 1 | // 2 | // AHCUser.m 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "AHCUser+Private.h" 10 | 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @implementation AHCUser 16 | 17 | #pragma mark - Initialization 18 | 19 | - (instancetype) init 20 | { 21 | return [self initWithName: @"" avatar: [NSImage imageNamed: NSImageNameUser] status: nil]; 22 | } 23 | 24 | - (instancetype) initWithName: (NSString*) name avatar: (NSImage*) avatar status: (nullable NSString*) statusOrNil 25 | { 26 | self = [super init]; 27 | 28 | if(!self) return nil; 29 | 30 | _name = name; 31 | 32 | _avatar = avatar; 33 | 34 | _status = statusOrNil; 35 | 36 | return self; 37 | } 38 | 39 | @end 40 | 41 | NS_ASSUME_NONNULL_END 42 | -------------------------------------------------------------------------------- /Sample/Sources/AHCUserTableCellView+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // AHCUserTableCellView+Private.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "AHCUserTableCellView.h" 10 | 11 | @interface AHCUserTableCellView () 12 | 13 | @property(readwrite, strong, nonatomic) IBOutlet NSImageView* avatarView; 14 | 15 | @property(readwrite, strong, nonatomic) IBOutlet NSView* centeringContainer; 16 | 17 | @property(readwrite, strong, nonatomic) IBOutlet NSTextField* nameLabel; 18 | 19 | @property(readwrite, strong, nonatomic) IBOutlet NSLayoutConstraint* nameLabelBottomConstraint; 20 | 21 | @property(readwrite, strong, nonatomic) IBOutlet NSTextField* statusLabel; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Sample/Sources/AHCUserTableCellView.h: -------------------------------------------------------------------------------- 1 | // 2 | // AHCUserTableCellView.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // * * *. 12 | 13 | @class AHCUser; 14 | 15 | // * * *. 16 | 17 | @interface AHCUserTableCellView : KSPAutomaticHeightCalculationTableCellView 18 | 19 | @property(readwrite, strong, atomic, nullable) AHCUser* objectValue; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Sample/Sources/AHCUserTableCellView.m: -------------------------------------------------------------------------------- 1 | // 2 | // AHCUserTableCellView.m 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "AHCUserTableCellView+Private.h" 10 | 11 | #import "AHCUser.h" 12 | 13 | // * * *. 14 | 15 | static void* ObjectValueKVOContext; 16 | 17 | // * * *. 18 | 19 | @implementation AHCUserTableCellView 20 | 21 | @dynamic objectValue; 22 | 23 | #pragma mark - Cleanup 24 | 25 | - (void) dealloc 26 | { 27 | [self removeObserver: self forKeyPath: NSStringFromSelector(@selector(objectValue)) context: &ObjectValueKVOContext]; 28 | } 29 | 30 | #pragma mark - KSPAutomaticHeightCalculationTableCellView Overrides 31 | 32 | + (BOOL) hasFixedHeight 33 | { 34 | return YES; 35 | } 36 | 37 | #pragma mark - 38 | 39 | - (void) awakeFromNib 40 | { 41 | [super awakeFromNib]; 42 | 43 | // * * *. 44 | 45 | [self addObserver: self forKeyPath: NSStringFromSelector(@selector(objectValue)) options: 0 context: &ObjectValueKVOContext]; 46 | } 47 | 48 | #pragma mark - Key-Value Observation 49 | 50 | - (void) observeValueForKeyPath: (NSString*) keyPath ofObject: (id) object change: (NSDictionary*) change context: (void*) context 51 | { 52 | if(context == &ObjectValueKVOContext) 53 | { 54 | // Avatar. 55 | self.avatarView.image = self.objectValue.avatar; 56 | 57 | // Name. 58 | self.nameLabel.objectValue = self.objectValue.name; 59 | 60 | // Status. 61 | const BOOL shouldHaveStatusLabelInTheUI = (self.objectValue.status.length > 0); 62 | 63 | if(shouldHaveStatusLabelInTheUI) 64 | { 65 | if(!self.statusLabel.superview) 66 | { 67 | [self.centeringContainer removeConstraint: self.nameLabelBottomConstraint]; 68 | 69 | self.statusLabel.translatesAutoresizingMaskIntoConstraints = NO; 70 | 71 | [self.centeringContainer addSubview: self.statusLabel]; 72 | 73 | NSDictionary* const views = @{@"nameLabel": self.nameLabel, @"statusLabel": self.statusLabel}; 74 | 75 | [self.centeringContainer addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @"H:|[statusLabel]-(>=0)-|" options: 0 metrics: nil views: views]]; 76 | 77 | [self.centeringContainer addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @"V:[nameLabel]-2-[statusLabel]|" options: 0 metrics: nil views: views]]; 78 | } 79 | } 80 | else 81 | { 82 | if(self.statusLabel.superview) 83 | { 84 | [self.statusLabel removeFromSuperview]; 85 | 86 | self.nameLabelBottomConstraint = [NSLayoutConstraint constraintWithItem: self.nameLabel attribute: NSLayoutAttributeBottom relatedBy: NSLayoutRelationEqual toItem: self.centeringContainer attribute: NSLayoutAttributeBottom multiplier: 1 constant: 0]; 87 | 88 | [self.centeringContainer addConstraint: self.nameLabelBottomConstraint]; 89 | } 90 | } 91 | 92 | self.statusLabel.objectValue = self.objectValue.status; 93 | } 94 | else 95 | { 96 | [super observeValueForKeyPath: keyPath ofObject: object change: change context: context]; 97 | } 98 | } 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /Sample/Sources/AHCUsersViewController+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // AHCUsersViewController+Private.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "AHCUsersViewController.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface AHCUsersViewController () 14 | 15 | @property(readwrite, strong, nonatomic) IBOutlet NSTableView* tableView; 16 | 17 | @property(readwrite, strong, nonatomic) IBOutlet NSTableColumn* mainColumn; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Sample/Sources/AHCUsersViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AHCUsersViewController.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface AHCUsersViewController : NSViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Sample/Sources/AHCUsersViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AHCUsersViewController.m 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "AHCUsersViewController+Private.h" 10 | 11 | #import "AHCUser.h" 12 | 13 | #import "AHCUserTableCellView.h" 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @implementation AHCUsersViewController 18 | { 19 | NSArray* _users; 20 | } 21 | 22 | #pragma mark - 23 | 24 | - (void) awakeFromNib 25 | { 26 | [super awakeFromNib]; 27 | 28 | // * * *. 29 | 30 | [self loadUsers]; 31 | 32 | [self registerCells]; 33 | 34 | // * * *. 35 | 36 | [self.tableView reloadData]; 37 | } 38 | 39 | #pragma mark - Private Methods 40 | 41 | - (void) loadUsers 42 | { 43 | NSURL* const URL = [[NSBundle mainBundle] URLForResource: @"Users" withExtension: @"plist"]; 44 | 45 | NSData* const data = [NSData dataWithContentsOfURL: URL]; 46 | 47 | NSError* error; 48 | 49 | NSArray* const userDictionariesOrNil = [NSPropertyListSerialization propertyListWithData: data options: NSPropertyListImmutable format: nil error: &error]; 50 | 51 | if(userDictionariesOrNil) 52 | { 53 | NSMutableArray* const mutableUsers = [NSMutableArray arrayWithCapacity: userDictionariesOrNil.count]; 54 | 55 | for(NSDictionary* userDictionary in userDictionariesOrNil) 56 | { 57 | NSString* _Nullable const avatarNameOrNil = userDictionary[@"avatarName"]; 58 | 59 | NSImage* const avatar = ((avatarNameOrNil.length > 0)? [NSImage imageNamed: avatarNameOrNil] : [NSImage imageNamed: NSImageNameUser]); 60 | 61 | AHCUser* const user = [[AHCUser alloc] initWithName: userDictionary[@"name"] avatar: avatar status: userDictionary[@"status"]]; 62 | 63 | [mutableUsers addObject: user]; 64 | } 65 | 66 | _users = [mutableUsers copy]; 67 | } 68 | else 69 | { 70 | NSLog(@"%@", error); 71 | } 72 | } 73 | 74 | - (void) registerCells 75 | { 76 | NSString* const className = NSStringFromClass([AHCUserTableCellView class]); 77 | 78 | [self.tableView registerNib: [[NSNib alloc] initWithNibNamed: className bundle: nil] forIdentifier: className]; 79 | } 80 | 81 | #pragma mark - NSTableViewDataSource Protocol Implementation 82 | 83 | - (NSInteger) numberOfRowsInTableView: (NSTableView*) tableView 84 | { 85 | return _users.count; 86 | } 87 | 88 | - (nullable id) tableView: (NSTableView*) tableView objectValueForTableColumn: (nullable NSTableColumn*) tableColumn row: (NSInteger) row 89 | { 90 | return _users[row]; 91 | } 92 | 93 | #pragma mark - NSTableViewDelegate Protocol Implementation 94 | 95 | - (nullable NSView*) tableView: (NSTableView*) tableView viewForTableColumn: (nullable NSTableColumn*) tableColumn row: (NSInteger) row 96 | { 97 | NSString* const className = NSStringFromClass([AHCUserTableCellView class]); 98 | 99 | return [tableView makeViewWithIdentifier: className owner: nil]; 100 | } 101 | 102 | - (CGFloat) tableView: (NSTableView*) tableView heightOfRow: (NSInteger) row 103 | { 104 | return [AHCUserTableCellView heightWithRepresentedObject: _users[row] width: self.mainColumn.width]; 105 | } 106 | 107 | @end 108 | 109 | NS_ASSUME_NONNULL_END 110 | -------------------------------------------------------------------------------- /Sample/Sources/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Sample 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Sample/Sources/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Sample 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | #import "AHCUsersViewController.h" 12 | 13 | #import "AHCMessagesViewController.h" 14 | 15 | @interface AppDelegate () 16 | 17 | @property(weak) IBOutlet NSWindow* window; 18 | 19 | @property(readwrite, strong, nonatomic) IBOutlet NSView* leftPane; 20 | 21 | @property(readwrite, strong, nonatomic) IBOutlet NSView* rightPane; 22 | 23 | @end 24 | 25 | @implementation AppDelegate 26 | { 27 | AHCUsersViewController* _usersViewController; 28 | 29 | AHCMessagesViewController* _messagesViewController; 30 | } 31 | 32 | #pragma mark - NSApplicationDelegate Protocol Implementation 33 | 34 | - (void) applicationDidFinishLaunching: (NSNotification*) aNotification 35 | { 36 | {{ 37 | _usersViewController = [[AHCUsersViewController alloc] initWithNibName: @"AHCUsersView" bundle: nil]; 38 | 39 | _usersViewController.view.translatesAutoresizingMaskIntoConstraints = NO; 40 | 41 | [self.leftPane addSubview: _usersViewController.view]; 42 | 43 | // * * *. 44 | 45 | NSDictionary* const views = @{@"usersView": _usersViewController.view}; 46 | 47 | [self.leftPane addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @"H:|[usersView(>=150@1000)]|" options: 0 metrics: nil views: views]]; 48 | 49 | [self.leftPane addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @"V:|[usersView(>=150@1000)]|" options: 0 metrics: nil views: views]]; 50 | }} 51 | 52 | // * * *. 53 | 54 | {{ 55 | _messagesViewController = [[AHCMessagesViewController alloc] initWithNibName: @"AHCMessagesView" bundle: nil]; 56 | 57 | _messagesViewController.view.translatesAutoresizingMaskIntoConstraints = NO; 58 | 59 | [self.rightPane addSubview: _messagesViewController.view]; 60 | 61 | // * * *. 62 | 63 | NSDictionary* const views = @{@"messagesView": _messagesViewController.view}; 64 | 65 | [self.rightPane addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @"H:|[messagesView(>=200@1000)]|" options: 0 metrics: nil views: views]]; 66 | 67 | [self.rightPane addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @"V:|[messagesView(>=150@1000)]|" options: 0 metrics: nil views: views]]; 68 | }} 69 | } 70 | 71 | - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) sender 72 | { 73 | return YES; 74 | } 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /Sample/Sources/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Sample 4 | // 5 | // Created by Konstantin Pavlikhin on 01.09.16. 6 | // Copyright © 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /Sources/KSPAutomaticHeightCalculationTableCellView+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // KSPAutomaticHeightCalculationTableCellView+Private.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 13.10.14. 6 | // Copyright (c) 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "KSPAutomaticHeightCalculationTableCellView.h" 10 | 11 | @interface KSPAutomaticHeightCalculationTableCellView () 12 | 13 | /// A bundle to look for a corresponding nib file. Default implementation returns the main bundle. 14 | + (nonnull NSBundle*) correspondingBundle; 15 | 16 | /// Subclasses should override this method and return YES if they have a fixed height. By default returns NO. 17 | + (BOOL) hasFixedHeight; 18 | 19 | /// Specifies if a cell instance is used as a prototype. 20 | @property(readwrite, assign, nonatomic, getter=isPrototype) BOOL prototype; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Sources/KSPAutomaticHeightCalculationTableCellView.h: -------------------------------------------------------------------------------- 1 | // 2 | // KSPAutomaticHeightCalculationTableCellView.h 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 13.10.14. 6 | // Copyright (c) 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // * * *. 12 | 13 | @class KSPAutomaticHeightCalculationTableCellView; 14 | 15 | // * * *. 16 | 17 | typedef void (^KSPTableCellViewConfigurationBlock)(KSPAutomaticHeightCalculationTableCellView* _Nonnull); 18 | 19 | // * * *. 20 | 21 | /// This class is responsible for instantiation and height measurement of a "dummy" table cell view. 22 | @interface KSPAutomaticHeightCalculationTableCellView : NSTableCellView 23 | 24 | /// Override to return a corresponding nib name. Default implementation simply returns the class name. 25 | + (nonnull NSString*) correspondingNibName; 26 | 27 | /// Given a content object, width of a presenting table column and a cell configuration block calculates the minimum possible height of a cell. 28 | + (CGFloat) heightWithRepresentedObject: (nullable id) object width: (CGFloat) width configurationBlock: (nullable KSPTableCellViewConfigurationBlock) blockOrNil; 29 | 30 | + (CGFloat) heightWithRepresentedObject: (nullable id) object width: (CGFloat) width; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Sources/KSPAutomaticHeightCalculationTableCellView.m: -------------------------------------------------------------------------------- 1 | // 2 | // KSPAutomaticHeightCalculationTableCellView.m 3 | // KSPAutomaticHeightCalculationTableCellView 4 | // 5 | // Created by Konstantin Pavlikhin on 13.10.14. 6 | // Copyright (c) 2016 Konstantin Pavlikhin. All rights reserved. 7 | // 8 | 9 | #import "KSPAutomaticHeightCalculationTableCellView+Private.h" 10 | 11 | #import 12 | 13 | @implementation KSPAutomaticHeightCalculationTableCellView 14 | 15 | #pragma mark - NSView Overrides 16 | 17 | + (BOOL) requiresConstraintBasedLayout 18 | { 19 | return YES; 20 | } 21 | 22 | #pragma mark - Prototype Cell View 23 | 24 | + (nullable KSPAutomaticHeightCalculationTableCellView*) prototypeCell 25 | { 26 | return objc_getAssociatedObject(self, @selector(prototypeCell)); 27 | } 28 | 29 | + (void) setPrototypeCell: (nullable KSPAutomaticHeightCalculationTableCellView*) prototypeCell 30 | { 31 | objc_setAssociatedObject(self, @selector(prototypeCell), prototypeCell, OBJC_ASSOCIATION_RETAIN); 32 | } 33 | 34 | #pragma mark - Width Constraint 35 | 36 | + (nullable NSLayoutConstraint*) widthConstraint 37 | { 38 | return objc_getAssociatedObject(self, @selector(widthConstraint)); 39 | } 40 | 41 | + (void) setWidthConstraint: (nullable NSLayoutConstraint*) widthConstraint 42 | { 43 | objc_setAssociatedObject(self, @selector(widthConstraint), widthConstraint, OBJC_ASSOCIATION_RETAIN); 44 | } 45 | 46 | #pragma mark - Cached Height 47 | 48 | + (nullable NSNumber*) cachedHeight 49 | { 50 | return objc_getAssociatedObject(self, @selector(cachedHeight)); 51 | } 52 | 53 | + (void) setCachedheight: (nullable NSNumber*) cachedHeight 54 | { 55 | objc_setAssociatedObject(self, @selector(cachedHeight), cachedHeight, OBJC_ASSOCIATION_RETAIN); 56 | } 57 | 58 | + (BOOL) hasCachedHeight 59 | { 60 | return ([self cachedHeight] != nil); 61 | } 62 | 63 | #pragma mark - 64 | 65 | + (nonnull NSString*) correspondingNibName 66 | { 67 | return NSStringFromClass([self class]); 68 | } 69 | 70 | + (nonnull NSBundle*) correspondingBundle 71 | { 72 | return [NSBundle mainBundle]; 73 | } 74 | 75 | + (BOOL) hasFixedHeight 76 | { 77 | return NO; 78 | } 79 | 80 | + (CGFloat) heightWithRepresentedObject: (nullable id) object width: (CGFloat) width configurationBlock: (nullable KSPTableCellViewConfigurationBlock) blockOrNil 81 | { 82 | // If we have a fixed-height prototype and height has already been calculated — return the cached value. 83 | if([self hasFixedHeight] && [self hasCachedHeight]) 84 | { 85 | return [self cachedHeight].doubleValue; 86 | } 87 | 88 | // Give a prototype cell a chance to reset any applied customizations. 89 | [[self prototypeCell] prepareForReuse]; 90 | 91 | if(![self prototypeCell]) 92 | { 93 | // Instantiate a prototype cell. 94 | NSArray* topLevelObjects = nil; 95 | 96 | __unused const BOOL result = [[[NSNib alloc] initWithNibNamed: [self correspondingNibName] bundle: [self correspondingBundle]] instantiateWithOwner: nil topLevelObjects: &topLevelObjects]; 97 | 98 | NSAssert(result, @"Unable to instantiate nib file."); 99 | 100 | [self setPrototypeCell: [[topLevelObjects filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: @"self isKindOfClass: %@", self]] firstObject]]; 101 | 102 | // Let the cell instance know that it will be used as a prototype. 103 | [self prototypeCell].prototype = YES; 104 | 105 | // Keep the constraint for performance considerations and vary its 'constant' property. 106 | [self setWidthConstraint: [NSLayoutConstraint constraintWithItem: [self prototypeCell] attribute: NSLayoutAttributeWidth relatedBy: NSLayoutRelationEqual toItem: nil attribute: NSLayoutAttributeNotAnAttribute multiplier: 1 constant: 0]]; 107 | 108 | [[self prototypeCell] addConstraint: [self widthConstraint]]; 109 | } 110 | 111 | [self widthConstraint].constant = width; 112 | 113 | // Fill the cell with information. 114 | [self prototypeCell].objectValue = object; 115 | 116 | // Let the passed block configure the cell. 117 | if(blockOrNil) blockOrNil([self prototypeCell]); 118 | 119 | // Ensure that layout is up to date. 120 | [[self prototypeCell] layoutSubtreeIfNeeded]; 121 | 122 | // Calculate and store the minimum possible height. 123 | [self setCachedheight: @([[self prototypeCell] fittingSize].height)]; 124 | 125 | // For a fixed-height cells these objects are no longer needed. 126 | if([self hasFixedHeight]) 127 | { 128 | // Release the prototype cell. 129 | [self setPrototypeCell: nil]; 130 | 131 | // Release the width constraint. 132 | [self setWidthConstraint: nil]; 133 | } 134 | 135 | NSAssert([self cachedHeight].doubleValue > 0, @"Calculated cell height is zero. Table view will complain!"); 136 | 137 | return [self cachedHeight].doubleValue; 138 | } 139 | 140 | + (CGFloat) heightWithRepresentedObject: (nullable id) object width: (CGFloat) width 141 | { 142 | return [self heightWithRepresentedObject: object width: width configurationBlock: nil]; 143 | } 144 | 145 | @end 146 | --------------------------------------------------------------------------------