├── .DS_Store ├── ChatHan.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ ├── a123.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── lee.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── a123.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ │ └── xcschememanagement.plist │ └── lee.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── ChatHan.xcscheme │ └── xcschememanagement.plist ├── ChatHan ├── .DS_Store ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── .DS_Store │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── camera.imageset │ │ ├── Contents.json │ │ ├── camera@2x.png │ │ └── camera@3x.png │ ├── emoji.imageset │ │ ├── emoji@2x.png │ │ ├── emoji@3x.png │ │ └── Contents.json │ ├── image.imageset │ │ ├── Contents.json │ │ ├── image@2x.png │ │ └── image@3x.png │ ├── keyboard.imageset │ │ ├── Contents.json │ │ ├── keyboard@2x.png │ │ └── keyboard@3x.png │ ├── record.imageset │ │ ├── Contents.json │ │ ├── record@2x.png │ │ └── record@3x.png │ ├── wechatvoice3.imageset │ │ ├── Contents.json │ │ ├── wechatvoice3@2x.png │ │ └── wechatvoice3@3x.png │ ├── wechatvoice3_0.imageset │ │ ├── Contents.json │ │ ├── wechatvoice3_0@2x.png │ │ └── wechatvoice3_0@3x.png │ └── wechatvoice3_1.imageset │ │ ├── Contents.json │ │ ├── wechatvoice3_1@2x.png │ │ └── wechatvoice3_1@3x.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── CSBigView.h ├── CSBigView.m ├── CSEmojiCollectionViewCell.h ├── CSEmojiCollectionViewCell.m ├── CSMessageCell.h ├── CSMessageCell.m ├── CSMessageModel.h ├── CSMessageModel.m ├── CSRecord.h ├── CSRecord.m ├── ConstantPart.h ├── EmojiView.h ├── EmojiView.m ├── ISEmojiList.plist ├── Info.plist ├── UIImage+Han.h ├── UIImage+Han.m ├── UILabel+Han.h ├── UILabel+Han.m ├── ViewController.h ├── ViewController.m ├── dd.png ├── ll.png ├── m.png ├── main.m ├── me.png ├── mm.png ├── other.png ├── ss.png └── w.png ├── ChatHanTests ├── ChatHanTests.m └── Info.plist └── ChatHanUITests ├── ChatHanUITests.m └── Info.plist /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/.DS_Store -------------------------------------------------------------------------------- /ChatHan.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9B3B826E1FE40F8F003F9626 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3B826D1FE40F8F003F9626 /* main.m */; }; 11 | 9B3B82711FE40F8F003F9626 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3B82701FE40F8F003F9626 /* AppDelegate.m */; }; 12 | 9B3B82771FE40F8F003F9626 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9B3B82751FE40F8F003F9626 /* Main.storyboard */; }; 13 | 9B3B82791FE40F8F003F9626 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9B3B82781FE40F8F003F9626 /* Assets.xcassets */; }; 14 | 9B3B827C1FE40F8F003F9626 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9B3B827A1FE40F8F003F9626 /* LaunchScreen.storyboard */; }; 15 | 9B3B82871FE40F8F003F9626 /* ChatHanTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3B82861FE40F8F003F9626 /* ChatHanTests.m */; }; 16 | 9B3B82921FE40F8F003F9626 /* ChatHanUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3B82911FE40F8F003F9626 /* ChatHanUITests.m */; }; 17 | 9B3B82A91FE4102D003F9626 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3B82A01FE4102D003F9626 /* ViewController.m */; }; 18 | 9B3B82AA1FE4102D003F9626 /* CSMessageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3B82A21FE4102D003F9626 /* CSMessageModel.m */; }; 19 | 9B3B82AB1FE4102D003F9626 /* CSMessageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3B82A41FE4102D003F9626 /* CSMessageCell.m */; }; 20 | 9B3B82AC1FE4102D003F9626 /* UILabel+Han.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3B82A61FE4102D003F9626 /* UILabel+Han.m */; }; 21 | 9B3B82AD1FE4102D003F9626 /* UIImage+Han.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3B82A81FE4102D003F9626 /* UIImage+Han.m */; }; 22 | 9B3B82B11FE4217D003F9626 /* m.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B3B82B01FE4217D003F9626 /* m.png */; }; 23 | 9B3B82B31FE42186003F9626 /* w.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B3B82B21FE42186003F9626 /* w.png */; }; 24 | 9B4C0EBC1FE6436E00CF91C7 /* CSBigView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B4C0EBB1FE6436E00CF91C7 /* CSBigView.m */; }; 25 | 9B4C0EBE1FE6720400CF91C7 /* ISEmojiList.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9B4C0EBD1FE6720400CF91C7 /* ISEmojiList.plist */; }; 26 | 9B4C0EC11FE6724200CF91C7 /* EmojiView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B4C0EC01FE6724100CF91C7 /* EmojiView.m */; }; 27 | 9B4C0ECC1FE67C9F00CF91C7 /* CSEmojiCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B4C0ECB1FE67C9F00CF91C7 /* CSEmojiCollectionViewCell.m */; }; 28 | 9BC1BBF81FE53F0E00183A27 /* me.png in Resources */ = {isa = PBXBuildFile; fileRef = 9BC1BBF71FE53F0E00183A27 /* me.png */; }; 29 | 9BC1BBFA1FE53F1700183A27 /* other.png in Resources */ = {isa = PBXBuildFile; fileRef = 9BC1BBF91FE53F1700183A27 /* other.png */; }; 30 | 9BC1BBFC1FE5464900183A27 /* dd.png in Resources */ = {isa = PBXBuildFile; fileRef = 9BC1BBFB1FE5464900183A27 /* dd.png */; }; 31 | 9BC1BBFE1FE5465100183A27 /* ll.png in Resources */ = {isa = PBXBuildFile; fileRef = 9BC1BBFD1FE5465100183A27 /* ll.png */; }; 32 | 9BC1BC001FE5465900183A27 /* mm.png in Resources */ = {isa = PBXBuildFile; fileRef = 9BC1BBFF1FE5465900183A27 /* mm.png */; }; 33 | 9BC1BC021FE5466200183A27 /* ss.png in Resources */ = {isa = PBXBuildFile; fileRef = 9BC1BC011FE5466200183A27 /* ss.png */; }; 34 | 9D46A2AA1FE7625A002BF26D /* CSRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D46A2A81FE76259002BF26D /* CSRecord.m */; }; 35 | 9D46A2AD1FE76271002BF26D /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D46A2AC1FE76271002BF26D /* AVFoundation.framework */; }; 36 | /* End PBXBuildFile section */ 37 | 38 | /* Begin PBXContainerItemProxy section */ 39 | 9B3B82831FE40F8F003F9626 /* PBXContainerItemProxy */ = { 40 | isa = PBXContainerItemProxy; 41 | containerPortal = 9B3B82611FE40F8F003F9626 /* Project object */; 42 | proxyType = 1; 43 | remoteGlobalIDString = 9B3B82681FE40F8F003F9626; 44 | remoteInfo = ChatHan; 45 | }; 46 | 9B3B828E1FE40F8F003F9626 /* PBXContainerItemProxy */ = { 47 | isa = PBXContainerItemProxy; 48 | containerPortal = 9B3B82611FE40F8F003F9626 /* Project object */; 49 | proxyType = 1; 50 | remoteGlobalIDString = 9B3B82681FE40F8F003F9626; 51 | remoteInfo = ChatHan; 52 | }; 53 | /* End PBXContainerItemProxy section */ 54 | 55 | /* Begin PBXFileReference section */ 56 | 9B3B82691FE40F8F003F9626 /* ChatHan.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ChatHan.app; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | 9B3B826D1FE40F8F003F9626 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 58 | 9B3B826F1FE40F8F003F9626 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 59 | 9B3B82701FE40F8F003F9626 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 60 | 9B3B82761FE40F8F003F9626 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 61 | 9B3B82781FE40F8F003F9626 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 62 | 9B3B827B1FE40F8F003F9626 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 63 | 9B3B827D1FE40F8F003F9626 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 64 | 9B3B82821FE40F8F003F9626 /* ChatHanTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ChatHanTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | 9B3B82861FE40F8F003F9626 /* ChatHanTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChatHanTests.m; sourceTree = ""; }; 66 | 9B3B82881FE40F8F003F9626 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 67 | 9B3B828D1FE40F8F003F9626 /* ChatHanUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ChatHanUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 68 | 9B3B82911FE40F8F003F9626 /* ChatHanUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChatHanUITests.m; sourceTree = ""; }; 69 | 9B3B82931FE40F8F003F9626 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 70 | 9B3B829F1FE4102D003F9626 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 71 | 9B3B82A01FE4102D003F9626 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 72 | 9B3B82A11FE4102D003F9626 /* CSMessageModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSMessageModel.h; sourceTree = ""; }; 73 | 9B3B82A21FE4102D003F9626 /* CSMessageModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSMessageModel.m; sourceTree = ""; }; 74 | 9B3B82A31FE4102D003F9626 /* CSMessageCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSMessageCell.h; sourceTree = ""; }; 75 | 9B3B82A41FE4102D003F9626 /* CSMessageCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSMessageCell.m; sourceTree = ""; }; 76 | 9B3B82A51FE4102D003F9626 /* UILabel+Han.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UILabel+Han.h"; sourceTree = ""; }; 77 | 9B3B82A61FE4102D003F9626 /* UILabel+Han.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UILabel+Han.m"; sourceTree = ""; }; 78 | 9B3B82A71FE4102D003F9626 /* UIImage+Han.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Han.h"; sourceTree = ""; }; 79 | 9B3B82A81FE4102D003F9626 /* UIImage+Han.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Han.m"; sourceTree = ""; }; 80 | 9B3B82AE1FE41091003F9626 /* ConstantPart.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ConstantPart.h; sourceTree = ""; }; 81 | 9B3B82B01FE4217D003F9626 /* m.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = m.png; sourceTree = ""; }; 82 | 9B3B82B21FE42186003F9626 /* w.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = w.png; sourceTree = ""; }; 83 | 9B4C0EBA1FE6436E00CF91C7 /* CSBigView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSBigView.h; sourceTree = ""; }; 84 | 9B4C0EBB1FE6436E00CF91C7 /* CSBigView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSBigView.m; sourceTree = ""; }; 85 | 9B4C0EBD1FE6720400CF91C7 /* ISEmojiList.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ISEmojiList.plist; sourceTree = ""; }; 86 | 9B4C0EBF1FE6724100CF91C7 /* EmojiView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EmojiView.h; sourceTree = ""; }; 87 | 9B4C0EC01FE6724100CF91C7 /* EmojiView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EmojiView.m; sourceTree = ""; }; 88 | 9B4C0ECA1FE67C9F00CF91C7 /* CSEmojiCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSEmojiCollectionViewCell.h; sourceTree = ""; }; 89 | 9B4C0ECB1FE67C9F00CF91C7 /* CSEmojiCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSEmojiCollectionViewCell.m; sourceTree = ""; }; 90 | 9BC1BBF71FE53F0E00183A27 /* me.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = me.png; sourceTree = ""; }; 91 | 9BC1BBF91FE53F1700183A27 /* other.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = other.png; sourceTree = ""; }; 92 | 9BC1BBFB1FE5464900183A27 /* dd.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dd.png; sourceTree = ""; }; 93 | 9BC1BBFD1FE5465100183A27 /* ll.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ll.png; sourceTree = ""; }; 94 | 9BC1BBFF1FE5465900183A27 /* mm.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mm.png; sourceTree = ""; }; 95 | 9BC1BC011FE5466200183A27 /* ss.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ss.png; sourceTree = ""; }; 96 | 9D46A2A81FE76259002BF26D /* CSRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSRecord.m; sourceTree = ""; }; 97 | 9D46A2A91FE7625A002BF26D /* CSRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSRecord.h; sourceTree = ""; }; 98 | 9D46A2AC1FE76271002BF26D /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 99 | /* End PBXFileReference section */ 100 | 101 | /* Begin PBXFrameworksBuildPhase section */ 102 | 9B3B82661FE40F8F003F9626 /* Frameworks */ = { 103 | isa = PBXFrameworksBuildPhase; 104 | buildActionMask = 2147483647; 105 | files = ( 106 | 9D46A2AD1FE76271002BF26D /* AVFoundation.framework in Frameworks */, 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | 9B3B827F1FE40F8F003F9626 /* Frameworks */ = { 111 | isa = PBXFrameworksBuildPhase; 112 | buildActionMask = 2147483647; 113 | files = ( 114 | ); 115 | runOnlyForDeploymentPostprocessing = 0; 116 | }; 117 | 9B3B828A1FE40F8F003F9626 /* Frameworks */ = { 118 | isa = PBXFrameworksBuildPhase; 119 | buildActionMask = 2147483647; 120 | files = ( 121 | ); 122 | runOnlyForDeploymentPostprocessing = 0; 123 | }; 124 | /* End PBXFrameworksBuildPhase section */ 125 | 126 | /* Begin PBXGroup section */ 127 | 9B3B82601FE40F8F003F9626 = { 128 | isa = PBXGroup; 129 | children = ( 130 | 9B3B826B1FE40F8F003F9626 /* ChatHan */, 131 | 9B3B82851FE40F8F003F9626 /* ChatHanTests */, 132 | 9B3B82901FE40F8F003F9626 /* ChatHanUITests */, 133 | 9B3B826A1FE40F8F003F9626 /* Products */, 134 | 9D46A2AB1FE76271002BF26D /* Frameworks */, 135 | ); 136 | sourceTree = ""; 137 | }; 138 | 9B3B826A1FE40F8F003F9626 /* Products */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 9B3B82691FE40F8F003F9626 /* ChatHan.app */, 142 | 9B3B82821FE40F8F003F9626 /* ChatHanTests.xctest */, 143 | 9B3B828D1FE40F8F003F9626 /* ChatHanUITests.xctest */, 144 | ); 145 | name = Products; 146 | sourceTree = ""; 147 | }; 148 | 9B3B826B1FE40F8F003F9626 /* ChatHan */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 9B4C0EBD1FE6720400CF91C7 /* ISEmojiList.plist */, 152 | 9BC1BC011FE5466200183A27 /* ss.png */, 153 | 9BC1BBFF1FE5465900183A27 /* mm.png */, 154 | 9BC1BBFD1FE5465100183A27 /* ll.png */, 155 | 9BC1BBFB1FE5464900183A27 /* dd.png */, 156 | 9BC1BBF71FE53F0E00183A27 /* me.png */, 157 | 9BC1BBF91FE53F1700183A27 /* other.png */, 158 | 9B3B82B21FE42186003F9626 /* w.png */, 159 | 9B3B82B01FE4217D003F9626 /* m.png */, 160 | 9B3B82AE1FE41091003F9626 /* ConstantPart.h */, 161 | 9B3B826F1FE40F8F003F9626 /* AppDelegate.h */, 162 | 9B3B82701FE40F8F003F9626 /* AppDelegate.m */, 163 | 9B3B829F1FE4102D003F9626 /* ViewController.h */, 164 | 9B3B82A01FE4102D003F9626 /* ViewController.m */, 165 | 9B3B82A11FE4102D003F9626 /* CSMessageModel.h */, 166 | 9B3B82A21FE4102D003F9626 /* CSMessageModel.m */, 167 | 9B3B82A31FE4102D003F9626 /* CSMessageCell.h */, 168 | 9B3B82A41FE4102D003F9626 /* CSMessageCell.m */, 169 | 9B4C0EBA1FE6436E00CF91C7 /* CSBigView.h */, 170 | 9B4C0EBB1FE6436E00CF91C7 /* CSBigView.m */, 171 | 9B3B82A51FE4102D003F9626 /* UILabel+Han.h */, 172 | 9B3B82A61FE4102D003F9626 /* UILabel+Han.m */, 173 | 9B3B82A71FE4102D003F9626 /* UIImage+Han.h */, 174 | 9B3B82A81FE4102D003F9626 /* UIImage+Han.m */, 175 | 9B4C0EBF1FE6724100CF91C7 /* EmojiView.h */, 176 | 9B4C0EC01FE6724100CF91C7 /* EmojiView.m */, 177 | 9B4C0ECA1FE67C9F00CF91C7 /* CSEmojiCollectionViewCell.h */, 178 | 9B4C0ECB1FE67C9F00CF91C7 /* CSEmojiCollectionViewCell.m */, 179 | 9D46A2A91FE7625A002BF26D /* CSRecord.h */, 180 | 9D46A2A81FE76259002BF26D /* CSRecord.m */, 181 | 9B3B82751FE40F8F003F9626 /* Main.storyboard */, 182 | 9B3B82781FE40F8F003F9626 /* Assets.xcassets */, 183 | 9B3B827A1FE40F8F003F9626 /* LaunchScreen.storyboard */, 184 | 9B3B827D1FE40F8F003F9626 /* Info.plist */, 185 | 9B3B826C1FE40F8F003F9626 /* Supporting Files */, 186 | ); 187 | path = ChatHan; 188 | sourceTree = ""; 189 | }; 190 | 9B3B826C1FE40F8F003F9626 /* Supporting Files */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 9B3B826D1FE40F8F003F9626 /* main.m */, 194 | ); 195 | name = "Supporting Files"; 196 | sourceTree = ""; 197 | }; 198 | 9B3B82851FE40F8F003F9626 /* ChatHanTests */ = { 199 | isa = PBXGroup; 200 | children = ( 201 | 9B3B82861FE40F8F003F9626 /* ChatHanTests.m */, 202 | 9B3B82881FE40F8F003F9626 /* Info.plist */, 203 | ); 204 | path = ChatHanTests; 205 | sourceTree = ""; 206 | }; 207 | 9B3B82901FE40F8F003F9626 /* ChatHanUITests */ = { 208 | isa = PBXGroup; 209 | children = ( 210 | 9B3B82911FE40F8F003F9626 /* ChatHanUITests.m */, 211 | 9B3B82931FE40F8F003F9626 /* Info.plist */, 212 | ); 213 | path = ChatHanUITests; 214 | sourceTree = ""; 215 | }; 216 | 9D46A2AB1FE76271002BF26D /* Frameworks */ = { 217 | isa = PBXGroup; 218 | children = ( 219 | 9D46A2AC1FE76271002BF26D /* AVFoundation.framework */, 220 | ); 221 | name = Frameworks; 222 | sourceTree = ""; 223 | }; 224 | /* End PBXGroup section */ 225 | 226 | /* Begin PBXNativeTarget section */ 227 | 9B3B82681FE40F8F003F9626 /* ChatHan */ = { 228 | isa = PBXNativeTarget; 229 | buildConfigurationList = 9B3B82961FE40F8F003F9626 /* Build configuration list for PBXNativeTarget "ChatHan" */; 230 | buildPhases = ( 231 | 9B3B82651FE40F8F003F9626 /* Sources */, 232 | 9B3B82661FE40F8F003F9626 /* Frameworks */, 233 | 9B3B82671FE40F8F003F9626 /* Resources */, 234 | ); 235 | buildRules = ( 236 | ); 237 | dependencies = ( 238 | ); 239 | name = ChatHan; 240 | productName = ChatHan; 241 | productReference = 9B3B82691FE40F8F003F9626 /* ChatHan.app */; 242 | productType = "com.apple.product-type.application"; 243 | }; 244 | 9B3B82811FE40F8F003F9626 /* ChatHanTests */ = { 245 | isa = PBXNativeTarget; 246 | buildConfigurationList = 9B3B82991FE40F8F003F9626 /* Build configuration list for PBXNativeTarget "ChatHanTests" */; 247 | buildPhases = ( 248 | 9B3B827E1FE40F8F003F9626 /* Sources */, 249 | 9B3B827F1FE40F8F003F9626 /* Frameworks */, 250 | 9B3B82801FE40F8F003F9626 /* Resources */, 251 | ); 252 | buildRules = ( 253 | ); 254 | dependencies = ( 255 | 9B3B82841FE40F8F003F9626 /* PBXTargetDependency */, 256 | ); 257 | name = ChatHanTests; 258 | productName = ChatHanTests; 259 | productReference = 9B3B82821FE40F8F003F9626 /* ChatHanTests.xctest */; 260 | productType = "com.apple.product-type.bundle.unit-test"; 261 | }; 262 | 9B3B828C1FE40F8F003F9626 /* ChatHanUITests */ = { 263 | isa = PBXNativeTarget; 264 | buildConfigurationList = 9B3B829C1FE40F8F003F9626 /* Build configuration list for PBXNativeTarget "ChatHanUITests" */; 265 | buildPhases = ( 266 | 9B3B82891FE40F8F003F9626 /* Sources */, 267 | 9B3B828A1FE40F8F003F9626 /* Frameworks */, 268 | 9B3B828B1FE40F8F003F9626 /* Resources */, 269 | ); 270 | buildRules = ( 271 | ); 272 | dependencies = ( 273 | 9B3B828F1FE40F8F003F9626 /* PBXTargetDependency */, 274 | ); 275 | name = ChatHanUITests; 276 | productName = ChatHanUITests; 277 | productReference = 9B3B828D1FE40F8F003F9626 /* ChatHanUITests.xctest */; 278 | productType = "com.apple.product-type.bundle.ui-testing"; 279 | }; 280 | /* End PBXNativeTarget section */ 281 | 282 | /* Begin PBXProject section */ 283 | 9B3B82611FE40F8F003F9626 /* Project object */ = { 284 | isa = PBXProject; 285 | attributes = { 286 | LastUpgradeCheck = 0820; 287 | ORGANIZATIONNAME = lee; 288 | TargetAttributes = { 289 | 9B3B82681FE40F8F003F9626 = { 290 | CreatedOnToolsVersion = 8.2.1; 291 | ProvisioningStyle = Automatic; 292 | }; 293 | 9B3B82811FE40F8F003F9626 = { 294 | CreatedOnToolsVersion = 8.2.1; 295 | DevelopmentTeam = 87SDS4L42Y; 296 | ProvisioningStyle = Automatic; 297 | TestTargetID = 9B3B82681FE40F8F003F9626; 298 | }; 299 | 9B3B828C1FE40F8F003F9626 = { 300 | CreatedOnToolsVersion = 8.2.1; 301 | DevelopmentTeam = 87SDS4L42Y; 302 | ProvisioningStyle = Automatic; 303 | TestTargetID = 9B3B82681FE40F8F003F9626; 304 | }; 305 | }; 306 | }; 307 | buildConfigurationList = 9B3B82641FE40F8F003F9626 /* Build configuration list for PBXProject "ChatHan" */; 308 | compatibilityVersion = "Xcode 3.2"; 309 | developmentRegion = English; 310 | hasScannedForEncodings = 0; 311 | knownRegions = ( 312 | en, 313 | Base, 314 | ); 315 | mainGroup = 9B3B82601FE40F8F003F9626; 316 | productRefGroup = 9B3B826A1FE40F8F003F9626 /* Products */; 317 | projectDirPath = ""; 318 | projectRoot = ""; 319 | targets = ( 320 | 9B3B82681FE40F8F003F9626 /* ChatHan */, 321 | 9B3B82811FE40F8F003F9626 /* ChatHanTests */, 322 | 9B3B828C1FE40F8F003F9626 /* ChatHanUITests */, 323 | ); 324 | }; 325 | /* End PBXProject section */ 326 | 327 | /* Begin PBXResourcesBuildPhase section */ 328 | 9B3B82671FE40F8F003F9626 /* Resources */ = { 329 | isa = PBXResourcesBuildPhase; 330 | buildActionMask = 2147483647; 331 | files = ( 332 | 9BC1BC021FE5466200183A27 /* ss.png in Resources */, 333 | 9B3B827C1FE40F8F003F9626 /* LaunchScreen.storyboard in Resources */, 334 | 9BC1BBFE1FE5465100183A27 /* ll.png in Resources */, 335 | 9BC1BBFC1FE5464900183A27 /* dd.png in Resources */, 336 | 9B3B82B11FE4217D003F9626 /* m.png in Resources */, 337 | 9B3B82791FE40F8F003F9626 /* Assets.xcassets in Resources */, 338 | 9BC1BC001FE5465900183A27 /* mm.png in Resources */, 339 | 9BC1BBF81FE53F0E00183A27 /* me.png in Resources */, 340 | 9B3B82771FE40F8F003F9626 /* Main.storyboard in Resources */, 341 | 9B3B82B31FE42186003F9626 /* w.png in Resources */, 342 | 9BC1BBFA1FE53F1700183A27 /* other.png in Resources */, 343 | 9B4C0EBE1FE6720400CF91C7 /* ISEmojiList.plist in Resources */, 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | }; 347 | 9B3B82801FE40F8F003F9626 /* Resources */ = { 348 | isa = PBXResourcesBuildPhase; 349 | buildActionMask = 2147483647; 350 | files = ( 351 | ); 352 | runOnlyForDeploymentPostprocessing = 0; 353 | }; 354 | 9B3B828B1FE40F8F003F9626 /* Resources */ = { 355 | isa = PBXResourcesBuildPhase; 356 | buildActionMask = 2147483647; 357 | files = ( 358 | ); 359 | runOnlyForDeploymentPostprocessing = 0; 360 | }; 361 | /* End PBXResourcesBuildPhase section */ 362 | 363 | /* Begin PBXSourcesBuildPhase section */ 364 | 9B3B82651FE40F8F003F9626 /* Sources */ = { 365 | isa = PBXSourcesBuildPhase; 366 | buildActionMask = 2147483647; 367 | files = ( 368 | 9B4C0EC11FE6724200CF91C7 /* EmojiView.m in Sources */, 369 | 9B3B82A91FE4102D003F9626 /* ViewController.m in Sources */, 370 | 9B4C0EBC1FE6436E00CF91C7 /* CSBigView.m in Sources */, 371 | 9B3B82711FE40F8F003F9626 /* AppDelegate.m in Sources */, 372 | 9B3B826E1FE40F8F003F9626 /* main.m in Sources */, 373 | 9B3B82AB1FE4102D003F9626 /* CSMessageCell.m in Sources */, 374 | 9B3B82AC1FE4102D003F9626 /* UILabel+Han.m in Sources */, 375 | 9B3B82AA1FE4102D003F9626 /* CSMessageModel.m in Sources */, 376 | 9D46A2AA1FE7625A002BF26D /* CSRecord.m in Sources */, 377 | 9B3B82AD1FE4102D003F9626 /* UIImage+Han.m in Sources */, 378 | 9B4C0ECC1FE67C9F00CF91C7 /* CSEmojiCollectionViewCell.m in Sources */, 379 | ); 380 | runOnlyForDeploymentPostprocessing = 0; 381 | }; 382 | 9B3B827E1FE40F8F003F9626 /* Sources */ = { 383 | isa = PBXSourcesBuildPhase; 384 | buildActionMask = 2147483647; 385 | files = ( 386 | 9B3B82871FE40F8F003F9626 /* ChatHanTests.m in Sources */, 387 | ); 388 | runOnlyForDeploymentPostprocessing = 0; 389 | }; 390 | 9B3B82891FE40F8F003F9626 /* Sources */ = { 391 | isa = PBXSourcesBuildPhase; 392 | buildActionMask = 2147483647; 393 | files = ( 394 | 9B3B82921FE40F8F003F9626 /* ChatHanUITests.m in Sources */, 395 | ); 396 | runOnlyForDeploymentPostprocessing = 0; 397 | }; 398 | /* End PBXSourcesBuildPhase section */ 399 | 400 | /* Begin PBXTargetDependency section */ 401 | 9B3B82841FE40F8F003F9626 /* PBXTargetDependency */ = { 402 | isa = PBXTargetDependency; 403 | target = 9B3B82681FE40F8F003F9626 /* ChatHan */; 404 | targetProxy = 9B3B82831FE40F8F003F9626 /* PBXContainerItemProxy */; 405 | }; 406 | 9B3B828F1FE40F8F003F9626 /* PBXTargetDependency */ = { 407 | isa = PBXTargetDependency; 408 | target = 9B3B82681FE40F8F003F9626 /* ChatHan */; 409 | targetProxy = 9B3B828E1FE40F8F003F9626 /* PBXContainerItemProxy */; 410 | }; 411 | /* End PBXTargetDependency section */ 412 | 413 | /* Begin PBXVariantGroup section */ 414 | 9B3B82751FE40F8F003F9626 /* Main.storyboard */ = { 415 | isa = PBXVariantGroup; 416 | children = ( 417 | 9B3B82761FE40F8F003F9626 /* Base */, 418 | ); 419 | name = Main.storyboard; 420 | sourceTree = ""; 421 | }; 422 | 9B3B827A1FE40F8F003F9626 /* LaunchScreen.storyboard */ = { 423 | isa = PBXVariantGroup; 424 | children = ( 425 | 9B3B827B1FE40F8F003F9626 /* Base */, 426 | ); 427 | name = LaunchScreen.storyboard; 428 | sourceTree = ""; 429 | }; 430 | /* End PBXVariantGroup section */ 431 | 432 | /* Begin XCBuildConfiguration section */ 433 | 9B3B82941FE40F8F003F9626 /* Debug */ = { 434 | isa = XCBuildConfiguration; 435 | buildSettings = { 436 | ALWAYS_SEARCH_USER_PATHS = NO; 437 | CLANG_ANALYZER_NONNULL = YES; 438 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 439 | CLANG_CXX_LIBRARY = "libc++"; 440 | CLANG_ENABLE_MODULES = YES; 441 | CLANG_ENABLE_OBJC_ARC = YES; 442 | CLANG_WARN_BOOL_CONVERSION = YES; 443 | CLANG_WARN_CONSTANT_CONVERSION = YES; 444 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 445 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 446 | CLANG_WARN_EMPTY_BODY = YES; 447 | CLANG_WARN_ENUM_CONVERSION = YES; 448 | CLANG_WARN_INFINITE_RECURSION = YES; 449 | CLANG_WARN_INT_CONVERSION = YES; 450 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 451 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 452 | CLANG_WARN_UNREACHABLE_CODE = YES; 453 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 454 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 455 | COPY_PHASE_STRIP = NO; 456 | DEBUG_INFORMATION_FORMAT = dwarf; 457 | ENABLE_STRICT_OBJC_MSGSEND = YES; 458 | ENABLE_TESTABILITY = YES; 459 | GCC_C_LANGUAGE_STANDARD = gnu99; 460 | GCC_DYNAMIC_NO_PIC = NO; 461 | GCC_NO_COMMON_BLOCKS = YES; 462 | GCC_OPTIMIZATION_LEVEL = 0; 463 | GCC_PREPROCESSOR_DEFINITIONS = ( 464 | "DEBUG=1", 465 | "$(inherited)", 466 | ); 467 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 468 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 469 | GCC_WARN_UNDECLARED_SELECTOR = YES; 470 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 471 | GCC_WARN_UNUSED_FUNCTION = YES; 472 | GCC_WARN_UNUSED_VARIABLE = YES; 473 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 474 | MTL_ENABLE_DEBUG_INFO = YES; 475 | ONLY_ACTIVE_ARCH = YES; 476 | SDKROOT = iphoneos; 477 | TARGETED_DEVICE_FAMILY = "1,2"; 478 | }; 479 | name = Debug; 480 | }; 481 | 9B3B82951FE40F8F003F9626 /* Release */ = { 482 | isa = XCBuildConfiguration; 483 | buildSettings = { 484 | ALWAYS_SEARCH_USER_PATHS = NO; 485 | CLANG_ANALYZER_NONNULL = YES; 486 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 487 | CLANG_CXX_LIBRARY = "libc++"; 488 | CLANG_ENABLE_MODULES = YES; 489 | CLANG_ENABLE_OBJC_ARC = YES; 490 | CLANG_WARN_BOOL_CONVERSION = YES; 491 | CLANG_WARN_CONSTANT_CONVERSION = YES; 492 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 493 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 494 | CLANG_WARN_EMPTY_BODY = YES; 495 | CLANG_WARN_ENUM_CONVERSION = YES; 496 | CLANG_WARN_INFINITE_RECURSION = YES; 497 | CLANG_WARN_INT_CONVERSION = YES; 498 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 499 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 500 | CLANG_WARN_UNREACHABLE_CODE = YES; 501 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 502 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 503 | COPY_PHASE_STRIP = NO; 504 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 505 | ENABLE_NS_ASSERTIONS = NO; 506 | ENABLE_STRICT_OBJC_MSGSEND = YES; 507 | GCC_C_LANGUAGE_STANDARD = gnu99; 508 | GCC_NO_COMMON_BLOCKS = YES; 509 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 510 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 511 | GCC_WARN_UNDECLARED_SELECTOR = YES; 512 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 513 | GCC_WARN_UNUSED_FUNCTION = YES; 514 | GCC_WARN_UNUSED_VARIABLE = YES; 515 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 516 | MTL_ENABLE_DEBUG_INFO = NO; 517 | SDKROOT = iphoneos; 518 | TARGETED_DEVICE_FAMILY = "1,2"; 519 | VALIDATE_PRODUCT = YES; 520 | }; 521 | name = Release; 522 | }; 523 | 9B3B82971FE40F8F003F9626 /* Debug */ = { 524 | isa = XCBuildConfiguration; 525 | buildSettings = { 526 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 527 | DEVELOPMENT_TEAM = ""; 528 | INFOPLIST_FILE = ChatHan/Info.plist; 529 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 531 | PRODUCT_BUNDLE_IDENTIFIER = XC.ChatHan; 532 | PRODUCT_NAME = "$(TARGET_NAME)"; 533 | }; 534 | name = Debug; 535 | }; 536 | 9B3B82981FE40F8F003F9626 /* Release */ = { 537 | isa = XCBuildConfiguration; 538 | buildSettings = { 539 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 540 | DEVELOPMENT_TEAM = ""; 541 | INFOPLIST_FILE = ChatHan/Info.plist; 542 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 543 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 544 | PRODUCT_BUNDLE_IDENTIFIER = XC.ChatHan; 545 | PRODUCT_NAME = "$(TARGET_NAME)"; 546 | }; 547 | name = Release; 548 | }; 549 | 9B3B829A1FE40F8F003F9626 /* Debug */ = { 550 | isa = XCBuildConfiguration; 551 | buildSettings = { 552 | BUNDLE_LOADER = "$(TEST_HOST)"; 553 | DEVELOPMENT_TEAM = 87SDS4L42Y; 554 | INFOPLIST_FILE = ChatHanTests/Info.plist; 555 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 556 | PRODUCT_BUNDLE_IDENTIFIER = com.Lee.ChatHanTests; 557 | PRODUCT_NAME = "$(TARGET_NAME)"; 558 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ChatHan.app/ChatHan"; 559 | }; 560 | name = Debug; 561 | }; 562 | 9B3B829B1FE40F8F003F9626 /* Release */ = { 563 | isa = XCBuildConfiguration; 564 | buildSettings = { 565 | BUNDLE_LOADER = "$(TEST_HOST)"; 566 | DEVELOPMENT_TEAM = 87SDS4L42Y; 567 | INFOPLIST_FILE = ChatHanTests/Info.plist; 568 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 569 | PRODUCT_BUNDLE_IDENTIFIER = com.Lee.ChatHanTests; 570 | PRODUCT_NAME = "$(TARGET_NAME)"; 571 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ChatHan.app/ChatHan"; 572 | }; 573 | name = Release; 574 | }; 575 | 9B3B829D1FE40F8F003F9626 /* Debug */ = { 576 | isa = XCBuildConfiguration; 577 | buildSettings = { 578 | DEVELOPMENT_TEAM = 87SDS4L42Y; 579 | INFOPLIST_FILE = ChatHanUITests/Info.plist; 580 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 581 | PRODUCT_BUNDLE_IDENTIFIER = com.Lee.ChatHanUITests; 582 | PRODUCT_NAME = "$(TARGET_NAME)"; 583 | TEST_TARGET_NAME = ChatHan; 584 | }; 585 | name = Debug; 586 | }; 587 | 9B3B829E1FE40F8F003F9626 /* Release */ = { 588 | isa = XCBuildConfiguration; 589 | buildSettings = { 590 | DEVELOPMENT_TEAM = 87SDS4L42Y; 591 | INFOPLIST_FILE = ChatHanUITests/Info.plist; 592 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 593 | PRODUCT_BUNDLE_IDENTIFIER = com.Lee.ChatHanUITests; 594 | PRODUCT_NAME = "$(TARGET_NAME)"; 595 | TEST_TARGET_NAME = ChatHan; 596 | }; 597 | name = Release; 598 | }; 599 | /* End XCBuildConfiguration section */ 600 | 601 | /* Begin XCConfigurationList section */ 602 | 9B3B82641FE40F8F003F9626 /* Build configuration list for PBXProject "ChatHan" */ = { 603 | isa = XCConfigurationList; 604 | buildConfigurations = ( 605 | 9B3B82941FE40F8F003F9626 /* Debug */, 606 | 9B3B82951FE40F8F003F9626 /* Release */, 607 | ); 608 | defaultConfigurationIsVisible = 0; 609 | defaultConfigurationName = Release; 610 | }; 611 | 9B3B82961FE40F8F003F9626 /* Build configuration list for PBXNativeTarget "ChatHan" */ = { 612 | isa = XCConfigurationList; 613 | buildConfigurations = ( 614 | 9B3B82971FE40F8F003F9626 /* Debug */, 615 | 9B3B82981FE40F8F003F9626 /* Release */, 616 | ); 617 | defaultConfigurationIsVisible = 0; 618 | defaultConfigurationName = Release; 619 | }; 620 | 9B3B82991FE40F8F003F9626 /* Build configuration list for PBXNativeTarget "ChatHanTests" */ = { 621 | isa = XCConfigurationList; 622 | buildConfigurations = ( 623 | 9B3B829A1FE40F8F003F9626 /* Debug */, 624 | 9B3B829B1FE40F8F003F9626 /* Release */, 625 | ); 626 | defaultConfigurationIsVisible = 0; 627 | defaultConfigurationName = Release; 628 | }; 629 | 9B3B829C1FE40F8F003F9626 /* Build configuration list for PBXNativeTarget "ChatHanUITests" */ = { 630 | isa = XCConfigurationList; 631 | buildConfigurations = ( 632 | 9B3B829D1FE40F8F003F9626 /* Debug */, 633 | 9B3B829E1FE40F8F003F9626 /* Release */, 634 | ); 635 | defaultConfigurationIsVisible = 0; 636 | defaultConfigurationName = Release; 637 | }; 638 | /* End XCConfigurationList section */ 639 | }; 640 | rootObject = 9B3B82611FE40F8F003F9626 /* Project object */; 641 | } 642 | -------------------------------------------------------------------------------- /ChatHan.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ChatHan.xcodeproj/project.xcworkspace/xcuserdata/a123.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan.xcodeproj/project.xcworkspace/xcuserdata/a123.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ChatHan.xcodeproj/project.xcworkspace/xcuserdata/lee.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan.xcodeproj/project.xcworkspace/xcuserdata/lee.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ChatHan.xcodeproj/xcuserdata/a123.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ChatHan.xcodeproj/xcuserdata/a123.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ChatHan.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ChatHan.xcodeproj/xcuserdata/lee.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /ChatHan.xcodeproj/xcuserdata/lee.xcuserdatad/xcschemes/ChatHan.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /ChatHan.xcodeproj/xcuserdata/lee.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ChatHan.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9B3B82681FE40F8F003F9626 16 | 17 | primary 18 | 19 | 20 | 9B3B82811FE40F8F003F9626 21 | 22 | primary 23 | 24 | 25 | 9B3B828C1FE40F8F003F9626 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ChatHan/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/.DS_Store -------------------------------------------------------------------------------- /ChatHan/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ChatHan 4 | // 5 | // Created by lee on 2017/12/15. 6 | // Copyright © 2017年 lee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /ChatHan/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ChatHan 4 | // 5 | // Created by lee on 2017/12/15. 6 | // Copyright © 2017年 lee. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/.DS_Store -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/camera.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "camera@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "camera@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/camera.imageset/camera@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/camera.imageset/camera@2x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/camera.imageset/camera@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/camera.imageset/camera@3x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/emoji.imageset/ emoji@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/emoji.imageset/ emoji@2x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/emoji.imageset/ emoji@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/emoji.imageset/ emoji@3x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/emoji.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : " emoji@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : " emoji@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "image@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "image@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/image.imageset/image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/image.imageset/image@2x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/image.imageset/image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/image.imageset/image@3x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/keyboard.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "keyboard@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "keyboard@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/keyboard.imageset/keyboard@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/keyboard.imageset/keyboard@2x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/keyboard.imageset/keyboard@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/keyboard.imageset/keyboard@3x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/record.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "record@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "record@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/record.imageset/record@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/record.imageset/record@2x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/record.imageset/record@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/record.imageset/record@3x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/wechatvoice3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "wechatvoice3@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "wechatvoice3@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/wechatvoice3.imageset/wechatvoice3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/wechatvoice3.imageset/wechatvoice3@2x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/wechatvoice3.imageset/wechatvoice3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/wechatvoice3.imageset/wechatvoice3@3x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/wechatvoice3_0.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "wechatvoice3_0@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "wechatvoice3_0@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/wechatvoice3_0.imageset/wechatvoice3_0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/wechatvoice3_0.imageset/wechatvoice3_0@2x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/wechatvoice3_0.imageset/wechatvoice3_0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/wechatvoice3_0.imageset/wechatvoice3_0@3x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/wechatvoice3_1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "wechatvoice3_1@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "wechatvoice3_1@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/wechatvoice3_1.imageset/wechatvoice3_1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/wechatvoice3_1.imageset/wechatvoice3_1@2x.png -------------------------------------------------------------------------------- /ChatHan/Assets.xcassets/wechatvoice3_1.imageset/wechatvoice3_1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/Assets.xcassets/wechatvoice3_1.imageset/wechatvoice3_1@3x.png -------------------------------------------------------------------------------- /ChatHan/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ChatHan/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /ChatHan/CSBigView.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #import 4 | 5 | @interface CSBigView : UIView 6 | @property (nonatomic, strong) UIImageView *bigImageView; 7 | @property (nonatomic, assign) BOOL show; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /ChatHan/CSBigView.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | #import "CSBigView.h" 4 | 5 | 6 | #define ScreenWidth [UIScreen mainScreen].bounds.size.width 7 | #define ScreenHight [UIScreen mainScreen].bounds.size.height 8 | 9 | @implementation CSBigView 10 | 11 | - (instancetype)init 12 | { 13 | if (self = [super init]) 14 | { 15 | [self creatImageView]; 16 | } 17 | return self; 18 | } 19 | - (instancetype)initWithFrame:(CGRect)frame 20 | { 21 | if (self = [super initWithFrame:frame]) 22 | { 23 | [self creatImageView]; 24 | } 25 | return self; 26 | } 27 | - (void)creatImageView 28 | { 29 | 30 | self.backgroundColor = [UIColor blackColor]; 31 | 32 | if (_bigImageView == nil) 33 | { 34 | _bigImageView = [[UIImageView alloc] init]; 35 | _bigImageView.bounds = CGRectMake(0, 0, 10, 10); 36 | [self addSubview:_bigImageView]; 37 | } 38 | 39 | 40 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapClicked:)]; 41 | [self addGestureRecognizer:tap]; 42 | 43 | } 44 | -(void)tapClicked:(UITapGestureRecognizer *)sender 45 | { 46 | [self removeFromSuperview]; 47 | } 48 | -(void)setShow:(BOOL)show 49 | { 50 | _show = show; 51 | if (show) 52 | { 53 | CGSize size = _bigImageView.image.size; 54 | CGFloat bigHeight = size.height; 55 | CGFloat bigWidth = size.width; 56 | if (bigWidth >= ScreenWidth) 57 | { 58 | 59 | if (bigHeight/bigWidth <= ScreenHight/ScreenWidth) 60 | { 61 | bigHeight = bigHeight/bigWidth * ScreenWidth; 62 | bigWidth = ScreenWidth; 63 | } 64 | else 65 | { 66 | bigWidth = bigWidth/bigHeight * ScreenHight; 67 | bigHeight = ScreenHight; 68 | } 69 | } 70 | // else 71 | // { 72 | // if (bigHeight >= ScreenHight) 73 | // { 74 | // bigWidth = bigWidth/bigHeight * ScreenHight; 75 | // bigHeight = ScreenHight; 76 | // } 77 | // 78 | // } 79 | _bigImageView.center = self.center; 80 | _bigImageView.bounds = CGRectMake(0, 0, bigWidth, bigHeight); 81 | [[UIApplication sharedApplication].keyWindow addSubview:self]; 82 | } 83 | } 84 | @end 85 | -------------------------------------------------------------------------------- /ChatHan/CSEmojiCollectionViewCell.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #import 4 | 5 | @interface CSEmojiCollectionViewCell : UICollectionViewCell 6 | 7 | @property (nonatomic, strong) UILabel *emojiLabel; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /ChatHan/CSEmojiCollectionViewCell.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | #import "CSEmojiCollectionViewCell.h" 4 | 5 | @implementation CSEmojiCollectionViewCell 6 | - (id)initWithFrame:(CGRect)frame 7 | { 8 | self = [super initWithFrame:frame]; 9 | if (self) 10 | { 11 | _emojiLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; 12 | _emojiLabel.textAlignment = NSTextAlignmentCenter; 13 | [self.contentView addSubview:_emojiLabel]; 14 | } 15 | 16 | return self; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /ChatHan/CSMessageCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSMessageCell.h 3 | // XMPPChat 4 | // 5 | // Created by 123 on 2017/12/14. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @class CSMessageCell; 13 | @protocol CSMessageCellDelegate 14 | 15 | @optional 16 | - (void)messageCellSingleClickedWith:(CSMessageCell *)cell; 17 | 18 | @end 19 | 20 | 21 | 22 | @class CSMessageModel; 23 | 24 | @interface CSMessageCell : UITableViewCell 25 | 26 | 27 | +(instancetype)cellWithTableView:(UITableView *)tableView messageModel:(CSMessageModel *)model; 28 | 29 | @property (nonatomic, strong) UIImageView *voiceAnimationImageView; 30 | @property (nonatomic, strong) UIImageView *imageImageView; 31 | 32 | @property (nonatomic,strong) CSMessageModel* messageModel; 33 | @property (nonatomic, weak) id delegate; 34 | 35 | 36 | -(void)stopVoiceAnimation; 37 | -(void)startVoiceAnimation; 38 | //-(void)startSentMessageAnimation; 39 | //-(void)stopSentMessageAnimation; 40 | 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /ChatHan/CSMessageCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSMessageCell.m 3 | // XMPPChat 4 | // 5 | // Created by 123 on 2017/12/14. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import "CSMessageCell.h" 10 | #import "CSMessageModel.h" 11 | #import "ConstantPart.h" 12 | #import "UILabel+Han.h" 13 | #import "UIImage+Han.h" 14 | 15 | 16 | @interface CSMessageCell() 17 | 18 | @property (nonatomic, strong) UIImageView *logoImageView; 19 | @property (nonatomic, strong) UIImageView *bubbleImageView; 20 | @property (nonatomic, strong) UIImageView *voiceImageView; 21 | 22 | @property (nonatomic, strong) UILabel *messageLabel; 23 | @property (nonatomic, strong) UILabel *timeLabel; 24 | @property (nonatomic, strong) UIFont *textFont; 25 | 26 | 27 | 28 | 29 | @end 30 | @implementation CSMessageCell 31 | 32 | +(instancetype)cellWithTableView:(UITableView *)tableView messageModel:(CSMessageModel *)model{ 33 | 34 | static NSString *identifier = @"WeChatCell"; 35 | CSMessageCell *cell=[tableView dequeueReusableCellWithIdentifier:identifier]; 36 | if (cell ==nil) 37 | { 38 | cell = [[CSMessageCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; 39 | } 40 | cell.messageModel = model; 41 | 42 | return cell; 43 | } 44 | 45 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 46 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) 47 | { 48 | //初始化subViews 49 | self.selectionStyle=UITableViewCellSelectionStyleNone; 50 | [self creatSubViewTime]; 51 | [self creatSubViewBubble]; 52 | [self creatSubViewLogo]; 53 | [self creatSubViewMessage]; 54 | [self creatSubViewVoice]; 55 | [self creatSubViewAnimationVoice]; 56 | [self creatSubViewImage]; 57 | 58 | } 59 | return self; 60 | } 61 | #pragma mark - 创建子视图 62 | 63 | - (void)creatSubViewMessage 64 | { 65 | _messageLabel = [[UILabel alloc] init]; 66 | _messageLabel.hidden = YES; 67 | [self.contentView addSubview:_messageLabel]; 68 | _textFont=[UIFont fontWithName:FONT_REGULAR size:16]; 69 | _messageLabel.numberOfLines=0; 70 | _messageLabel.lineBreakMode=NSLineBreakByWordWrapping; 71 | _messageLabel.font = _textFont; 72 | _messageLabel.textColor=COLOR_444444; 73 | } 74 | 75 | - (void)creatSubViewTime 76 | { 77 | _timeLabel = [[UILabel alloc] init]; 78 | _timeLabel.hidden = YES; 79 | [self.contentView addSubview:_timeLabel]; 80 | _timeLabel.font=[UIFont fontWithName:FONT_REGULAR size:10]; 81 | _timeLabel.backgroundColor=COLOR_cecece; 82 | _timeLabel.textColor=COLOR_ffffff; 83 | _timeLabel.textAlignment=NSTextAlignmentCenter; 84 | _timeLabel.layer.masksToBounds=YES; 85 | _timeLabel.layer.cornerRadius=4; 86 | _timeLabel.layer.borderColor=[COLOR_cecece CGColor]; 87 | _timeLabel.layer.borderWidth=1; 88 | } 89 | 90 | - (void)creatSubViewLogo 91 | { 92 | _logoImageView = [[UIImageView alloc] init]; 93 | _logoImageView.hidden = YES; 94 | [self.contentView addSubview:_logoImageView]; 95 | } 96 | 97 | - (void)creatSubViewBubble 98 | { 99 | _bubbleImageView = [[UIImageView alloc] init]; 100 | _bubbleImageView.hidden = YES; 101 | _bubbleImageView.userInteractionEnabled = YES; 102 | [self.contentView addSubview:_bubbleImageView]; 103 | 104 | UILongPressGestureRecognizer *longPressGesture=[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressBubbleView:)]; 105 | [_bubbleImageView addGestureRecognizer:longPressGesture]; 106 | 107 | 108 | UITapGestureRecognizer * singleTap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap2:)]; 109 | [_bubbleImageView addGestureRecognizer:singleTap2]; 110 | } 111 | 112 | - (void)creatSubViewVoice 113 | { 114 | _voiceImageView = [[UIImageView alloc] init]; 115 | _voiceImageView.hidden = YES; 116 | [self.contentView addSubview:_voiceImageView]; 117 | } 118 | - (void)creatSubViewAnimationVoice 119 | { 120 | _voiceAnimationImageView = [[UIImageView alloc] init]; 121 | _voiceAnimationImageView.hidden = YES; 122 | [_voiceImageView addSubview:_voiceAnimationImageView]; 123 | } 124 | - (void)creatSubViewImage 125 | { 126 | _imageImageView = [[UIImageView alloc] init]; 127 | _imageImageView.hidden = YES; 128 | [self.contentView addSubview:_imageImageView]; 129 | } 130 | 131 | 132 | 133 | - (void)setMessageModel:(CSMessageModel *)messageModel { 134 | _messageModel = messageModel; 135 | 136 | 137 | _timeLabel.hidden = !messageModel.showMessageTime; 138 | _timeLabel.frame = [messageModel timeFrame]; 139 | _timeLabel.text = messageModel.messageTime; 140 | 141 | 142 | 143 | _logoImageView.hidden = NO; 144 | _logoImageView.frame = [messageModel logoFrame]; 145 | 146 | _bubbleImageView.hidden = NO; 147 | _bubbleImageView.frame = [messageModel bubbleFrame]; 148 | 149 | if (messageModel.messageSenderType == MessageSenderTypeMe) 150 | { 151 | _logoImageView.image = [UIImage imageNamed:@"w"]; 152 | _bubbleImageView.image = [[UIImage imageNamed:@"me"] stretchableImageWithLeftCapWidth:20 topCapHeight:40]; 153 | } 154 | else 155 | { 156 | _logoImageView.image = [UIImage imageNamed:@"m"]; 157 | _bubbleImageView.image = [[UIImage imageNamed:@"other"] stretchableImageWithLeftCapWidth:20 topCapHeight:40]; 158 | } 159 | 160 | 161 | switch (messageModel.messageType) 162 | { 163 | case MessageTypeText: 164 | _messageLabel.hidden = NO; 165 | _messageLabel.frame = [messageModel messageFrame]; 166 | _messageLabel.text = messageModel.messageText; 167 | _messageLabel.textAlignment = NSTextAlignmentLeft; 168 | 169 | break; 170 | case MessageTypeVoice: 171 | _voiceImageView.hidden = NO; 172 | _voiceImageView.frame = [messageModel voiceFrame]; 173 | _messageLabel.hidden = NO; 174 | _messageLabel.frame = [messageModel voiceFrame]; 175 | _messageLabel.textAlignment = messageModel.messageSenderType == MessageSenderTypeMe ? NSTextAlignmentLeft:NSTextAlignmentRight; 176 | _messageLabel.text = [NSString stringWithFormat:@"%ld''",(long)messageModel.duringTime]; 177 | _voiceAnimationImageView.hidden = NO; 178 | _voiceAnimationImageView.frame = [messageModel voiceAnimationFrame]; 179 | _voiceAnimationImageView.image=[UIImage imageNamed:@"wechatvoice3"]; 180 | _voiceAnimationImageView.animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:@"wechatvoice3"],[UIImage imageNamed:@"wechatvoice3_1"],[UIImage imageNamed:@"wechatvoice3_0"],[UIImage imageNamed:@"wechatvoice3_1"],[UIImage imageNamed:@"wechatvoice3"],nil]; 181 | 182 | _voiceAnimationImageView.animationDuration = 1; 183 | _voiceAnimationImageView.transform =messageModel.messageSenderType == MessageSenderTypeMe ? CGAffineTransformMakeRotation(M_PI) : CGAffineTransformMakeRotation(0); 184 | _voiceAnimationImageView.animationRepeatCount = -1; 185 | break; 186 | case MessageTypeImage: 187 | _imageImageView.hidden = NO; 188 | _imageImageView.frame = [messageModel imageFrame]; 189 | _imageImageView.image = messageModel.imageSmall; 190 | CGSize imageSize = [messageModel.imageSmall imageShowSize]; 191 | UIImageView *imageViewMask = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:_messageModel.messageSenderType == MessageSenderTypeMe ? @"me" :@"other"] stretchableImageWithLeftCapWidth:20 topCapHeight:40]]; 192 | imageViewMask.frame = CGRectMake(0, 0, imageSize.width, imageSize.height); 193 | _imageImageView.layer.mask = imageViewMask.layer; 194 | 195 | break; 196 | // default: 197 | // break; 198 | } 199 | 200 | 201 | 202 | } 203 | 204 | - (void)prepareForReuse { 205 | [super prepareForReuse]; 206 | 207 | //text voice image 208 | self.frame = CGRectMake(0, 0, AppFrameWidth, 44); 209 | _logoImageView.hidden = YES; 210 | _bubbleImageView.hidden = YES; 211 | _voiceImageView.hidden = YES; 212 | _messageLabel.hidden = YES; 213 | _timeLabel.hidden = YES; 214 | _imageImageView.hidden = YES; 215 | 216 | 217 | 218 | } 219 | 220 | #pragma 长按事件 221 | - (void)longPressBubbleView:(UILongPressGestureRecognizer *)sender { 222 | if (sender.state == UIGestureRecognizerStateBegan) 223 | { 224 | [self showMenuControllerInView:self bgView:sender.view]; 225 | } 226 | 227 | } 228 | - (void)showMenuControllerInView:(CSMessageCell *)inView 229 | bgView:(UIView *)supView 230 | { 231 | [self becomeFirstResponder]; 232 | 233 | CSMessageModel *messageModel=self.messageModel; 234 | 235 | UIMenuItem *copyTextItem1 = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyTextSender1:)]; 236 | UIMenuItem *copyTextItem2 = [[UIMenuItem alloc] initWithTitle:@"保存到相册" action:@selector(copyTextSender2:)]; 237 | UIMenuController *menu = [UIMenuController sharedMenuController]; 238 | [menu setTargetRect:supView.frame inView:inView]; 239 | [menu setArrowDirection:UIMenuControllerArrowDefault]; 240 | if (messageModel.messageType==MessageTypeText) 241 | { 242 | [menu setMenuItems:@[copyTextItem1]]; 243 | } 244 | else if (messageModel.messageType==MessageTypeImage) 245 | { 246 | [menu setMenuItems:@[copyTextItem2]]; 247 | } 248 | else if(messageModel.messageType==MessageTypeVoice) 249 | { 250 | } 251 | 252 | 253 | 254 | 255 | [menu setMenuVisible:YES animated:YES]; 256 | 257 | } 258 | #pragma mark 剪切板代理方法 259 | -(BOOL)canBecomeFirstResponder { 260 | NSLog(@"%s",__FUNCTION__); 261 | return YES; 262 | } 263 | 264 | -(BOOL)canPerformAction:(SEL)action withSender:(id)sender { 265 | if (action == @selector(copyTextSender1:)) { 266 | return true; 267 | } else if (action == @selector(copyTextSender2:)) { 268 | return true; 269 | } else { 270 | return false; 271 | } 272 | } 273 | -(void)copyTextSender1:(id)sender { 274 | 275 | UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; 276 | if (self.messageModel.messageText.length > 0) 277 | { 278 | pasteboard.string = self.messageModel.messageText; 279 | } 280 | } 281 | -(void)copyTextSender2:(id)sender { 282 | UIImageWriteToSavedPhotosAlbum(self.imageImageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 283 | } 284 | 285 | 286 | 287 | -(void)handleSingleTap2:(id)sender 288 | { 289 | if (self.delegate && [self.delegate respondsToSelector:@selector(messageCellSingleClickedWith:)]) 290 | { 291 | [self.delegate messageCellSingleClickedWith:self]; 292 | } 293 | } 294 | //开始录音动画 295 | - (void)startVoiceAnimation 296 | { 297 | [self.voiceAnimationImageView startAnimating]; 298 | } 299 | //结束录音动画 300 | - (void)stopVoiceAnimation 301 | { 302 | [self.voiceAnimationImageView stopAnimating]; 303 | } 304 | 305 | //保存到相册回调 306 | - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo 307 | { 308 | 309 | 310 | } 311 | 312 | - (void)awakeFromNib { 313 | [super awakeFromNib]; 314 | // Initialization code 315 | } 316 | 317 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 318 | [super setSelected:selected animated:animated]; 319 | 320 | // Configure the view for the selected state 321 | } 322 | 323 | @end 324 | -------------------------------------------------------------------------------- /ChatHan/CSMessageModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSMessageModel.h 3 | // XMPPChat 4 | // 5 | // Created by 123 on 2017/12/14. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | /* 13 | 消息类型 14 | */ 15 | typedef NS_OPTIONS(NSUInteger, MessageType) { 16 | MessageTypeText=1, 17 | MessageTypeVoice, 18 | MessageTypeImage 19 | 20 | 21 | }; 22 | 23 | 24 | /* 25 | 消息发送方 26 | */ 27 | typedef NS_OPTIONS(NSUInteger, MessageSenderType) { 28 | MessageSenderTypeMe=1, 29 | MessageSenderTypeOther 30 | 31 | }; 32 | 33 | 34 | 35 | /* 36 | 消息发送状态 37 | */ 38 | 39 | typedef NS_OPTIONS(NSUInteger, MessageSentStatus) { 40 | MessageSentStatusSended=1,//送达 41 | MessageSentStatusUnSended, //未发送 42 | MessageSentStatusSending, //正在发送 43 | 44 | }; 45 | 46 | /* 47 | 消息接收状态 48 | */ 49 | 50 | typedef NS_OPTIONS(NSUInteger, MessageReadStatus) { 51 | MessageReadStatusRead=1,//消息已读 52 | MessageReadStatusUnRead //消息未读 53 | 54 | }; 55 | 56 | 57 | /* 58 | 59 | 只有当消息送达的时候,才会出现 接收状态, 60 | 消息已读 和未读 仅仅针对自己 61 | 62 | 63 | 未送达显示红色, 64 | 发送中显示菊花 65 | 送达状态彼此互斥 66 | 67 | 68 | 69 | */ 70 | 71 | 72 | 73 | 74 | @interface CSMessageModel : NSObject 75 | 76 | 77 | @property (nonatomic, assign) MessageType messageType; 78 | @property (nonatomic, assign) MessageSenderType messageSenderType; 79 | @property (nonatomic, assign) MessageSentStatus messageSentStatus; 80 | @property (nonatomic, assign) MessageReadStatus messageReadStatus; 81 | /* 82 | 是否显示小时的时间 83 | */ 84 | @property (nonatomic, assign) BOOL showMessageTime; 85 | 86 | /* 87 | 消息时间 2017-09-11 11:11 88 | */ 89 | @property (nonatomic, retain) NSString *messageTime; 90 | 91 | 92 | /* 93 | 图像url 94 | */ 95 | @property (nonatomic, retain) NSString *logoUrl; 96 | 97 | /* 98 | 消息文本内容 99 | */ 100 | @property (nonatomic, retain) NSString *messageText; 101 | 102 | 103 | /* 104 | 音频时间 105 | */ 106 | 107 | @property (nonatomic, assign) NSInteger duringTime; 108 | /* 109 | 消息音频url 110 | */ 111 | @property (nonatomic, retain) NSString *voiceUrl; 112 | 113 | 114 | /* 115 | 图片文件 116 | */ 117 | @property (nonatomic, retain) NSString *imageUrl; 118 | 119 | /* 120 | 图片文件 121 | */ 122 | @property (nonatomic, retain) UIImage *imageSmall; 123 | 124 | 125 | - (CGRect)timeFrame; 126 | - (CGRect)logoFrame; 127 | - (CGRect)messageFrame; 128 | - (CGRect)voiceFrame; 129 | - (CGRect)voiceAnimationFrame; 130 | - (CGRect)bubbleFrame; 131 | - (CGRect)imageFrame; 132 | - (CGFloat)cellHeight; 133 | 134 | 135 | @end 136 | -------------------------------------------------------------------------------- /ChatHan/CSMessageModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSMessageModel.m 3 | // XMPPChat 4 | // 5 | // Created by 123 on 2017/12/14. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import "CSMessageModel.h" 10 | //#import "MessageHeader.h" 11 | #import "ConstantPart.h" 12 | #import "UIImage+Han.h" 13 | 14 | #define ScreenWidth [UIScreen mainScreen].bounds.size.width 15 | #define ScreenHight [UIScreen mainScreen].bounds.size.height 16 | 17 | 18 | 19 | @implementation CSMessageModel 20 | 21 | 22 | - (CGRect)timeFrame 23 | { 24 | CGRect rect = CGRectZero; 25 | if (self.showMessageTime) 26 | { 27 | CGSize size = [self labelAutoCalculateRectWith:self.messageTime Font:[UIFont fontWithName:FONT_REGULAR size:10] MaxSize:CGSizeMake(MAXFLOAT, 17)]; 28 | rect = CGRectMake((ScreenWidth - size.width)/2, 0, size.width + 10, 17); 29 | } 30 | 31 | return rect; 32 | } 33 | 34 | - (CGRect)logoFrame 35 | { 36 | 37 | CGRect timeRect = [self timeFrame]; 38 | 39 | CGRect rect = CGRectZero; 40 | if (self.messageSenderType == MessageSenderTypeMe) 41 | { 42 | rect = CGRectMake(ScreenWidth - 50,timeRect.size.height + 10, 40, 40); 43 | } 44 | else 45 | { 46 | rect = CGRectMake(10, timeRect.size.height + 10, 40, 40); 47 | } 48 | return rect; 49 | } 50 | 51 | 52 | - (CGRect)messageFrame 53 | { 54 | CGRect timeRect = [self timeFrame]; 55 | CGRect rect = CGRectZero; 56 | CGFloat maxWith = ScreenWidth * 0.7 - 60; 57 | CGSize size = [self labelAutoCalculateRectWith:self.messageText Font:[UIFont fontWithName:FONT_REGULAR size:16] MaxSize:CGSizeMake(maxWith, MAXFLOAT)]; 58 | if (self.messageText == nil) 59 | { 60 | return rect; 61 | } 62 | if (self.messageSenderType == MessageSenderTypeMe) 63 | { 64 | rect = CGRectMake(ScreenWidth * 0.3, timeRect.size.height + 10, maxWith - 5, size.height > 44 ? size.height : 44);; 65 | } 66 | else 67 | { 68 | rect = CGRectMake(65 , timeRect.size.height + 10 , maxWith, size.height > 44 ? size.height : 44); 69 | } 70 | return rect; 71 | } 72 | 73 | - (CGRect)voiceFrame 74 | { 75 | 76 | 77 | CGRect timeRect = [self timeFrame]; 78 | CGFloat timeLabelHeight = timeRect.size.height ; 79 | CGRect rect = CGRectZero; 80 | CGFloat maxWith = ScreenWidth * 0.7 - 60; 81 | if (self.duringTime <= 0) 82 | { 83 | return rect; 84 | } 85 | if (self.messageSenderType == MessageSenderTypeMe) 86 | { 87 | rect = CGRectMake(AppFrameWidth * 0.3 + 10 + maxWith - maxWith *(self.duringTime/20.0 > 1? 1 :self.duringTime/20.0), timeLabelHeight + 10, maxWith *(self.duringTime/20.0 > 1? 1 :self.duringTime/20.0), 44); 88 | } 89 | else 90 | { 91 | rect = CGRectMake(50, timeLabelHeight + 10 , maxWith *(self.duringTime/20.0 > 1? 1 :self.duringTime/20.0), 44); 92 | } 93 | return rect; 94 | } 95 | - (CGRect)voiceAnimationFrame 96 | { 97 | //12, 16 98 | CGRect voiceRect = [self voiceFrame]; 99 | CGRect rect = CGRectZero; 100 | if (self.messageSenderType == MessageSenderTypeMe) 101 | { 102 | rect.origin.x = voiceRect.size.width - 24; 103 | rect.origin.y = 14; 104 | rect.size.width = 12; 105 | rect.size.height = 16; 106 | 107 | } 108 | else 109 | { 110 | rect.origin.x = 12; 111 | rect.origin.y = 14; 112 | rect.size.width = 12; 113 | rect.size.height = 16; 114 | } 115 | return rect; 116 | } 117 | - (CGRect)imageFrame 118 | { 119 | CGRect timeRect = [self timeFrame]; 120 | CGFloat timeLabelHeight = timeRect.size.height; 121 | CGRect rect = CGRectZero; 122 | 123 | CGSize imageSize = [self.imageSmall imageShowSize]; 124 | 125 | if (self.imageSmall == nil) 126 | { 127 | return rect; 128 | } 129 | 130 | if (self.messageSenderType == MessageSenderTypeMe) 131 | { 132 | rect = CGRectMake(ScreenWidth - imageSize.width - 50, timeLabelHeight + 10, imageSize.width, imageSize.height); 133 | } 134 | else 135 | { 136 | rect = CGRectMake(50, timeLabelHeight + 10, imageSize.width, imageSize.height); 137 | } 138 | return rect; 139 | } 140 | - (CGRect)bubbleFrame 141 | { 142 | CGRect rect = CGRectZero; 143 | switch (self.messageType) 144 | { 145 | case MessageTypeText: 146 | rect = [self messageFrame]; 147 | rect.origin.x = rect.origin.x + (self.messageSenderType == MessageSenderTypeMe? -10 : -15); 148 | rect.size.width = rect.size.width + 25; 149 | break; 150 | case MessageTypeVoice: 151 | rect = [self voiceFrame]; 152 | break; 153 | case MessageTypeImage: 154 | rect = [self imageFrame]; 155 | 156 | break; 157 | default: 158 | break; 159 | } 160 | 161 | return rect; 162 | } 163 | - (CGFloat)cellHeight 164 | { 165 | return [self timeFrame].size.height + [self messageFrame].size.height + [self voiceFrame].size.height + [self imageFrame].size.height + 15; 166 | } 167 | 168 | - (CGSize)labelAutoCalculateRectWith:(NSString *)text Font:(UIFont *)textFont MaxSize:(CGSize)maxSize 169 | { 170 | NSDictionary *attributes = @{NSFontAttributeName: textFont}; 171 | CGRect rect = [text boundingRectWithSize:maxSize 172 | options:NSStringDrawingUsesLineFragmentOrigin 173 | attributes:attributes 174 | context:nil]; 175 | return rect.size; 176 | } 177 | @end 178 | -------------------------------------------------------------------------------- /ChatHan/CSRecord.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSRecord.h 3 | // Voice 4 | // 5 | // Created by 123 on 2017/12/7. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CSRecord : NSObject 12 | + (instancetype)ShareCSRecord; 13 | - (void)beginRecord; 14 | - (void)endRecord; 15 | //- (void)getVoicePath; 16 | //- (void)getVoiceFile; 17 | - (void)playRecord; 18 | @end 19 | -------------------------------------------------------------------------------- /ChatHan/CSRecord.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSRecord.m 3 | // Voice 4 | // 5 | // Created by 123 on 2017/12/7. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import "CSRecord.h" 10 | #import 11 | 12 | 13 | @interface CSRecord() 14 | @property (nonatomic,strong)AVAudioRecorder * audioRecorder;//音频录音机 15 | @property (nonatomic,strong)AVAudioPlayer * audioPlayer;//音频播放器,用于播放录音 16 | @end 17 | @implementation CSRecord 18 | + (instancetype)ShareCSRecord 19 | { 20 | static CSRecord *record = nil; 21 | static dispatch_once_t onceToken; 22 | dispatch_once(&onceToken, ^{ 23 | record = [[CSRecord alloc] init]; 24 | }); 25 | return record; 26 | } 27 | - (instancetype)init 28 | { 29 | if (self = [super init]) 30 | { 31 | } 32 | return self; 33 | } 34 | 35 | //录音文件的路径 36 | -(NSURL *)getSavePath 37 | { 38 | NSString * urlStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES ) lastObject]; 39 | urlStr = [urlStr stringByAppendingPathComponent:@"myRecord.caf"]; 40 | NSLog(@"file:path:%@",urlStr); 41 | NSURL * url = [NSURL fileURLWithPath:urlStr]; 42 | return url; 43 | } 44 | //设置音频格式 45 | -(NSDictionary *)getAudioSettion 46 | { 47 | NSMutableDictionary * dicM = [NSMutableDictionary dictionary]; 48 | //设置录音格式 49 | [dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey]; 50 | //设置录音采样率,8000是电话采样率,对于一般的录音已经够了 51 | [dicM setObject:@(8000) forKey:AVSampleRateKey]; 52 | //设置通道,这里采用单声道 53 | [dicM setObject:@(1) forKey:AVNumberOfChannelsKey]; 54 | //每个采样点位数,分为8,16,24,32 55 | [dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey]; 56 | //是否使用浮点数采样 57 | [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey]; 58 | //。。。。是他设置 59 | return dicM; 60 | } 61 | //获得录音机对象 62 | -(AVAudioRecorder * )audioRecorder 63 | { 64 | if (!_audioRecorder) { 65 | //创建录音文件保存路径 66 | NSURL * url =[self getSavePath]; 67 | //创建录音格式设置 68 | NSDictionary * setting = [self getAudioSettion]; 69 | //创建录音机 70 | NSError * error = nil; 71 | _audioRecorder = [[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error]; 72 | _audioRecorder.delegate = self; 73 | if(error) 74 | { 75 | NSLog(@"创建录音机对象发生错误,错误信息是:%@",error.localizedDescription); 76 | return nil; 77 | } 78 | 79 | } 80 | return _audioRecorder; 81 | 82 | } 83 | -(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag 84 | { 85 | AVURLAsset* audioAsset =[AVURLAsset URLAssetWithURL:[self getSavePath] options:nil]; 86 | CMTime audioDuration = audioAsset.duration; 87 | float audioDurationSeconds =CMTimeGetSeconds(audioDuration); 88 | NSLog(@"录音完成!-->%f",audioDurationSeconds); 89 | } 90 | 91 | //创建播放器 92 | -(AVAudioPlayer *)audioPlayer 93 | { 94 | 95 | _audioPlayer = nil; 96 | NSURL * url = [self getSavePath]; 97 | NSError * error = nil; 98 | _audioPlayer =[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error]; 99 | _audioPlayer.numberOfLoops = 0; 100 | _audioPlayer.delegate = self; 101 | [_audioPlayer prepareToPlay]; 102 | if (error) { 103 | NSLog(@"创建播放器过程出错:错误信息是:%@",error.localizedDescription); 104 | return nil; 105 | } 106 | 107 | return _audioPlayer; 108 | } 109 | - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag 110 | { 111 | NSLog(@"播放完了"); 112 | } 113 | 114 | - (void)beginRecord 115 | { 116 | AVAudioSession * audioSession = [AVAudioSession sharedInstance]; 117 | [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 118 | [audioSession setActive:YES error:nil]; 119 | if (![self.audioRecorder isRecording]) 120 | { 121 | [self.audioRecorder record]; 122 | } 123 | } 124 | - (void)endRecord 125 | { 126 | AVAudioSession *session = [AVAudioSession sharedInstance]; 127 | 128 | [session setCategory:AVAudioSessionCategoryPlayback error:nil]; 129 | 130 | [self.audioRecorder stop]; 131 | } 132 | - (void)playRecord 133 | { 134 | 135 | _audioPlayer = [self audioPlayer]; 136 | [_audioPlayer stop]; 137 | [_audioPlayer play]; 138 | } 139 | - (void)stopPlayRecord 140 | { 141 | _audioPlayer = [self audioPlayer]; 142 | [_audioPlayer stop]; 143 | } 144 | @end 145 | 146 | -------------------------------------------------------------------------------- /ChatHan/ConstantPart.h: -------------------------------------------------------------------------------- 1 | // 2 | 3 | // 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | #define RGBA(R,G,B,A) [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:A] 14 | #define RGB(R,G,B) [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:1.0] 15 | 16 | 17 | #define HEXRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0] 18 | #define HEXRGBA(rgbValue,a) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:a] 19 | 20 | 21 | #define AppFrameWidth [UIScreen mainScreen].bounds.size.width 22 | #define AppFrameHight [UIScreen mainScreen].bounds.size.height 23 | 24 | #define ISIOS7LATER ([[[UIDevice currentDevice] systemVersion] floatValue]>=7.0) 25 | 26 | #define ISIOS8LATER ([[[UIDevice currentDevice] systemVersion] floatValue]>=8.0) 27 | 28 | #define ISIOS9LATER ([[[UIDevice currentDevice] systemVersion] floatValue]>=9.0) 29 | 30 | #define ISIOS10LATER ([[[UIDevice currentDevice] systemVersion] floatValue]>=10.0) 31 | 32 | 33 | 34 | 35 | 36 | #define FONT_HEADTITLE [UIFont fontWithName:@"PingFangSC-Medium" size:24] 37 | 38 | #define NOTICE_LOGIN_SUC @"notice_login_suc" 39 | 40 | #define hiddenViewNotifaction @"hiddenViewNotifaction" 41 | #define loginViewShowNotifaction @"loginViewShowNotifaction" 42 | 43 | 44 | #define FONT_MEDIUM @"PingFangSC-Medium" 45 | #define FONT_REGULAR @"PingFangSC-Regular" 46 | #define FONT_SEMIBOLD @"PingFangSC-Semibold" 47 | #define FONT_SC @"PingFangSC" 48 | 49 | #define COLOR_ffffff HEXRGB(0xffffff) 50 | #define COLOR_f2f2f2 HEXRGB(0xf2f2f2) 51 | #define COLOR_f6f6f6 HEXRGB(0xf6f6f6) 52 | #define COLOR_a8a8a8 HEXRGB(0xa8a8a8) 53 | #define COLOR_444444 HEXRGB(0x444444) 54 | #define COLOR_f7f7f7 HEXRGB(0xf7f7f7) 55 | #define COLOR_e85b53 HEXRGB(0xe85b53) 56 | #define COLOR_666666 HEXRGB(0x666666) 57 | #define COLOR_bababa HEXRGB(0xbababa) 58 | #define COLOR_999999 HEXRGB(0x999999) 59 | #define COLOR_ececec HEXRGB(0xececec) 60 | #define COLOR_e6e6e6 HEXRGB(0xe6e6e6) 61 | #define COLOR_4ab495 HEXRGB(0x4ab495) 62 | #define COLOR_78879d HEXRGB(0x78879d) 63 | 64 | #define COLOR_313232 HEXRGB(0x313232) 65 | #define COLOR_abaaaa HEXRGB(0xabaaaa) 66 | #define COLOR_e3e3e3 HEXRGB(0xe3e3e3) 67 | #define COLOR_000000 HEXRGB(0x000000) 68 | #define COLOR_cecece HEXRGB(0xcecece) 69 | #define COLOR_2a9e39 HEXRGB(0x2a9e39) 70 | #define COLOR_c00000 HEXRGB(0xc00000) 71 | 72 | 73 | -------------------------------------------------------------------------------- /ChatHan/EmojiView.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | #import 6 | 7 | 8 | @protocol EmojiViewDelegate 9 | 10 | @optional 11 | - (void)emojiClicked:(NSString *)strEmoji; 12 | @end 13 | 14 | 15 | 16 | @interface EmojiView : UIView 17 | @property (nonatomic, assign) id delegate; 18 | @end 19 | -------------------------------------------------------------------------------- /ChatHan/EmojiView.m: -------------------------------------------------------------------------------- 1 | // 高度 220 2 | 3 | #import "EmojiView.h" 4 | #import "CSEmojiCollectionViewCell.h" 5 | 6 | #define ScreenWidth [UIScreen mainScreen].bounds.size.width 7 | #define ScreenHight [UIScreen mainScreen].bounds.size.height 8 | 9 | @interface EmojiView() 10 | { 11 | UICollectionView *_collectionView; 12 | NSArray *_dataArray; 13 | } 14 | @end 15 | 16 | @implementation EmojiView 17 | 18 | 19 | - (instancetype)init 20 | { 21 | if (self = [super init]) 22 | { 23 | [self creatEmojiView]; 24 | } 25 | return self; 26 | } 27 | 28 | - (instancetype)initWithFrame:(CGRect)frame 29 | { 30 | if (self = [super initWithFrame:frame]) 31 | { 32 | [self creatEmojiView]; 33 | } 34 | return self; 35 | } 36 | - (void)creatEmojiView 37 | { 38 | NSString *emojiPath = [[NSBundle mainBundle] pathForResource:@"ISEmojiList" ofType:@"plist"]; 39 | _dataArray = [NSArray arrayWithContentsOfFile:emojiPath]; 40 | 41 | 42 | UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc]init]; 43 | //同一行相邻两个cell的最小间距 44 | layout.minimumInteritemSpacing = 0; 45 | //最小两行之间的间距 46 | layout.minimumLineSpacing = 0; 47 | //这个是横向滑动 48 | // layout.scrollDirection=UICollectionViewScrollDirectionHorizontal; 49 | 50 | layout.itemSize = CGSizeMake(ScreenWidth/8, self.frame.size.height/3); 51 | 52 | 53 | _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) collectionViewLayout:layout]; 54 | _collectionView.backgroundColor=[UIColor whiteColor]; 55 | _collectionView.pagingEnabled = YES; 56 | _collectionView.delegate=self; 57 | _collectionView.dataSource=self; 58 | [self addSubview:_collectionView]; 59 | 60 | 61 | [_collectionView registerClass:[CSEmojiCollectionViewCell class] forCellWithReuseIdentifier:@"cellId"]; 62 | 63 | } 64 | 65 | //每一组有多少个cell 66 | -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ 67 | return _dataArray.count; 68 | } 69 | //每一个cell是什么 70 | -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 71 | CSEmojiCollectionViewCell *cell = (CSEmojiCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"cellId" forIndexPath:indexPath]; 72 | cell.emojiLabel.text = _dataArray[indexPath.row]; 73 | return cell; 74 | } 75 | //设置每个item的UIEdgeInsets 76 | - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section 77 | { 78 | return UIEdgeInsetsMake(0, 0, 0, 0); 79 | } 80 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 81 | { 82 | if (self.delegate && [self.delegate respondsToSelector:@selector(emojiClicked:)]) 83 | { 84 | NSString *strEmoji = _dataArray[indexPath.row]; 85 | [self.delegate emojiClicked:strEmoji]; 86 | } 87 | 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /ChatHan/ISEmojiList.plist: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /ChatHan/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh-n 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | NSPhotoLibraryUsageDescription 38 | 获取相册访问权限 39 | NSCameraUsageDescription 40 | 获取相机访问权限 41 | NSMicrophoneUsageDescription 42 | 获取录音访问权限 43 | UISupportedInterfaceOrientations~ipad 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationPortraitUpsideDown 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /ChatHan/UIImage+Han.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Han.h 3 | // XMPPChat 4 | // 5 | // Created by 123 on 2017/12/15. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (Han) 12 | -(CGSize)imageShowSize; 13 | @end 14 | -------------------------------------------------------------------------------- /ChatHan/UIImage+Han.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Han.m 3 | // XMPPChat 4 | // 5 | // Created by 123 on 2017/12/15. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import "UIImage+Han.h" 10 | #define MAX_IMAGE_W 141.0 11 | #define MAX_IMAGE_H 228.0 12 | @implementation UIImage (Han) 13 | /* 14 | 判断图片长度&宽度 15 | 16 | */ 17 | -(CGSize)imageShowSize{ 18 | 19 | CGFloat imageWith=self.size.width; 20 | CGFloat imageHeight=self.size.height; 21 | 22 | 23 | //宽度大于高度 24 | if (imageWith >= imageHeight) { 25 | // 宽度超过标准宽度 26 | /**/ 27 | if (imageWith > MAX_IMAGE_W) 28 | { 29 | return CGSizeMake(MAX_IMAGE_W, imageHeight*MAX_IMAGE_W/imageWith); 30 | } 31 | else 32 | { 33 | return self.size; 34 | } 35 | } 36 | else 37 | { 38 | /**/ 39 | if (imageHeight > MAX_IMAGE_H) 40 | { 41 | return CGSizeMake(imageWith*MAX_IMAGE_W/imageHeight, MAX_IMAGE_W); 42 | } 43 | else 44 | { 45 | return self.size; 46 | } 47 | } 48 | 49 | 50 | 51 | 52 | 53 | return CGSizeZero; 54 | } 55 | @end 56 | -------------------------------------------------------------------------------- /ChatHan/UILabel+Han.h: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+Han.h 3 | // XMPPChat 4 | // 5 | // Created by 123 on 2017/12/14. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UILabel (Han) 12 | - (void)cellType; 13 | - (CGSize)labelAutoCalculateRectWith:(NSString *)text Font:(UIFont *)textFont MaxSize:(CGSize)maxSize; 14 | @end 15 | -------------------------------------------------------------------------------- /ChatHan/UILabel+Han.m: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+Han.m 3 | // XMPPChat 4 | // 5 | // Created by 123 on 2017/12/14. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import "UILabel+Han.h" 10 | 11 | @implementation UILabel (Han) 12 | - (void)cellType 13 | { 14 | 15 | } 16 | - (CGSize)labelAutoCalculateRectWith:(NSString *)text Font:(UIFont *)textFont MaxSize:(CGSize)maxSize 17 | { 18 | NSDictionary *attributes = @{NSFontAttributeName: textFont}; 19 | CGRect rect = [text boundingRectWithSize:maxSize 20 | options:NSStringDrawingUsesLineFragmentOrigin 21 | attributes:attributes 22 | context:nil]; 23 | return rect.size; 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /ChatHan/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // XMPPChat 4 | // 5 | // Created by 123 on 2017/12/14. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ChatHan/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // XMPPChat 4 | // 5 | // Created by 123 on 2017/12/14. 6 | // Copyright © 2017年 123. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "CSMessageCell.h" 11 | #import "CSMessageModel.h" 12 | #import "CSBigView.h" 13 | #import "EmojiView.h" 14 | #import "CSRecord.h" 15 | 16 | #define ScreenWidth [UIScreen mainScreen].bounds.size.width 17 | #define ScreenHight [UIScreen mainScreen].bounds.size.height 18 | 19 | @interface ViewController () 20 | 21 | @property (weak, nonatomic) IBOutlet UITableView *tableView; 22 | @property (nonatomic, strong) NSMutableArray *dataArray; 23 | @property (nonatomic, assign) CGFloat nowHeight; 24 | @property (nonatomic, strong) UIImageView *photoImageView; 25 | @property (nonatomic, strong) CSBigView *bigImageView; 26 | @property (nonatomic, strong) EmojiView *ev; 27 | @property (nonatomic, strong) UIImage *photoImage; 28 | @property (nonatomic, strong) NSIndexPath *selectIndex; 29 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *tableBottomConstraint; 30 | 31 | @end 32 | 33 | @implementation ViewController 34 | 35 | - (void)viewDidLoad { 36 | [super viewDidLoad]; 37 | // Do any additional setup after loading the view, typically from a nib. 38 | _dataArray = [NSMutableArray arrayWithCapacity:0]; 39 | 40 | _tableView.backgroundColor = [[UIColor alloc] initWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1]; 41 | 42 | 43 | _bigImageView = [[CSBigView alloc] init]; 44 | _bigImageView.frame = [UIScreen mainScreen].bounds; 45 | 46 | _ev = [[EmojiView alloc] initWithFrame:CGRectMake(0, ScreenHight - 180, ScreenWidth, 180)]; 47 | _ev.hidden = YES; 48 | _ev.delegate = self; 49 | [self.view addSubview:_ev]; 50 | 51 | 52 | CSMessageModel *model = [[CSMessageModel alloc] init]; 53 | model.showMessageTime=YES; 54 | model.messageTime = @"2017年12月12日 16:37"; 55 | model.messageSenderType = MessageSenderTypeMe; 56 | model.messageType = MessageTypeText; 57 | model.messageText = @"推开窗看见星星依然守在夜空中心中不免多了些暖暖的感动一闪一闪的光努力把黑夜变亮气氛如此安详你在我的生命中是那最闪亮的星一直在无声夜空守护着我们的梦这世界那么大 我的爱只想要你懂 陪伴我孤寂旅程你知道我的梦 你知道我的痛你知道我们感受都相同 就算有再大的风也挡不住勇敢的冲动 努力的往前飞 再累也无所谓 黑夜过后的光芒有多美 分享你我的力量就能把对方的路照亮 我想我们都一样 渴望梦想的光芒 这一路喜悦彷徨 不要轻易说失望 回到最初时光 当时的你多么坚强 那鼓励让我难忘"; 58 | [_dataArray addObject:model]; 59 | 60 | model = [[CSMessageModel alloc] init]; 61 | model.showMessageTime=YES; 62 | model.messageSenderType = MessageSenderTypeOther; 63 | model.messageType = MessageTypeText; 64 | model.messageText = @"我们都一样"; 65 | model.messageTime = @"16:40"; 66 | [_dataArray addObject:model]; 67 | 68 | 69 | model = [[CSMessageModel alloc] init]; 70 | model.showMessageTime=YES; 71 | model.messageSenderType = MessageSenderTypeMe; 72 | model.messageType = MessageTypeText; 73 | model.messageText = @"我们都一样"; 74 | model.messageTime = @"16:40"; 75 | [_dataArray addObject:model]; 76 | 77 | 78 | 79 | model = [[CSMessageModel alloc] init]; 80 | model.showMessageTime=YES; 81 | model.messageTime = @"2017年12月12日 16:37"; 82 | model.messageSenderType = MessageSenderTypeOther; 83 | model.messageType = MessageTypeText; 84 | model.messageText = @"推开窗看见星星依然守在夜空中心中不免多了些暖暖的感动一闪一闪的光努力把黑夜变亮气氛如此安详你在我的生命中是那最闪亮的星一直在无声夜空守护着我们的梦这世界那么大 我的爱只想要你懂 陪伴我孤寂旅程你知道我的梦 你知道我的痛你知道我们感受都相同 就算有再大的风也挡不住勇敢的冲动 努力的往前飞 再累也无所谓 黑夜过后的光芒有多美 分享你我的力量就能把对方的路照亮 我想我们都一样 渴望梦想的光芒 这一路喜悦彷徨 不要轻易说失望 回到最初时光 当时的你多么坚强 那鼓励让我难忘"; 85 | [_dataArray addObject:model]; 86 | 87 | 88 | model = [[CSMessageModel alloc] init]; 89 | model.showMessageTime=YES; 90 | model.messageSenderType = MessageSenderTypeMe; 91 | model.messageType = MessageTypeVoice; 92 | model.duringTime = 30; 93 | model.messageTime = @"16:40"; 94 | [_dataArray addObject:model]; 95 | 96 | model = [[CSMessageModel alloc] init]; 97 | model.showMessageTime=YES; 98 | model.messageSenderType = MessageSenderTypeMe; 99 | model.messageType = MessageTypeVoice; 100 | model.duringTime = 15; 101 | model.messageTime = @"16:40"; 102 | [_dataArray addObject:model]; 103 | 104 | model = [[CSMessageModel alloc] init]; 105 | model.showMessageTime=YES; 106 | model.messageSenderType = MessageSenderTypeMe; 107 | model.messageType = MessageTypeVoice; 108 | model.duringTime = 100; 109 | model.messageTime = @"16:40"; 110 | [_dataArray addObject:model]; 111 | 112 | 113 | model = [[CSMessageModel alloc] init]; 114 | model.showMessageTime=YES; 115 | model.messageSenderType = MessageSenderTypeOther; 116 | model.messageType = MessageTypeVoice; 117 | model.duringTime = 20; 118 | model.messageTime = @"16:40"; 119 | [_dataArray addObject:model]; 120 | 121 | model = [[CSMessageModel alloc] init]; 122 | model.showMessageTime=YES; 123 | model.messageSenderType = MessageSenderTypeOther; 124 | model.messageType = MessageTypeVoice; 125 | model.duringTime = 10; 126 | model.messageTime = @"16:40"; 127 | [_dataArray addObject:model]; 128 | 129 | model = [[CSMessageModel alloc] init]; 130 | model.showMessageTime=YES; 131 | model.messageSenderType = MessageSenderTypeOther; 132 | model.messageType = MessageTypeVoice; 133 | model.duringTime = 15; 134 | model.messageTime = @"16:40"; 135 | [_dataArray addObject:model]; 136 | 137 | model = [[CSMessageModel alloc] init]; 138 | model.showMessageTime=YES; 139 | model.messageSenderType = MessageSenderTypeMe; 140 | model.messageType = MessageTypeImage; 141 | model.imageSmall = [UIImage imageNamed:@"w"]; 142 | model.messageTime = @"16:40"; 143 | [_dataArray addObject:model]; 144 | 145 | 146 | model = [[CSMessageModel alloc] init]; 147 | model.showMessageTime=YES; 148 | model.messageSenderType = MessageSenderTypeOther; 149 | model.messageType = MessageTypeImage; 150 | model.imageSmall = [UIImage imageNamed:@"mm"]; 151 | model.messageTime = @"16:40"; 152 | [_dataArray addObject:model]; 153 | 154 | 155 | model = [[CSMessageModel alloc] init]; 156 | model.showMessageTime=YES; 157 | model.messageSenderType = MessageSenderTypeMe; 158 | model.messageType = MessageTypeImage; 159 | model.imageSmall = [UIImage imageNamed:@"w"]; 160 | model.messageTime = @"16:40"; 161 | [_dataArray addObject:model]; 162 | 163 | model = [[CSMessageModel alloc] init]; 164 | model.showMessageTime=YES; 165 | model.messageSenderType = MessageSenderTypeOther; 166 | model.messageType = MessageTypeImage; 167 | model.imageSmall = [UIImage imageNamed:@"m"]; 168 | model.messageTime = @"16:40"; 169 | [_dataArray addObject:model]; 170 | 171 | model = [[CSMessageModel alloc] init]; 172 | model.showMessageTime=YES; 173 | model.messageSenderType = MessageSenderTypeMe; 174 | model.messageType = MessageTypeImage; 175 | model.imageSmall = [UIImage imageNamed:@"dd"]; 176 | model.messageTime = @"16:40"; 177 | [_dataArray addObject:model]; 178 | 179 | model = [[CSMessageModel alloc] init]; 180 | model.showMessageTime=YES; 181 | model.messageSenderType = MessageSenderTypeOther; 182 | model.messageType = MessageTypeImage; 183 | model.imageSmall = [UIImage imageNamed:@"ll"]; 184 | model.messageTime = @"16:40"; 185 | [_dataArray addObject:model]; 186 | 187 | model = [[CSMessageModel alloc] init]; 188 | model.showMessageTime=YES; 189 | model.messageSenderType = MessageSenderTypeMe; 190 | model.messageType = MessageTypeImage; 191 | model.imageSmall = [UIImage imageNamed:@"ss"]; 192 | model.messageTime = @"16:40"; 193 | [_dataArray addObject:model]; 194 | 195 | model = [[CSMessageModel alloc] init]; 196 | model.showMessageTime=YES; 197 | model.messageSenderType = MessageSenderTypeOther; 198 | model.messageType = MessageTypeImage; 199 | model.imageSmall = [UIImage imageNamed:@"m"]; 200 | model.messageTime = @"16:40"; 201 | [_dataArray addObject:model]; 202 | 203 | 204 | _tableView.separatorColor = [UIColor clearColor]; 205 | 206 | 207 | 208 | 209 | 210 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; 211 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; 212 | } 213 | -(void)keyboardWillShow:(NSNotification *)aNotification 214 | { 215 | _ev.hidden = YES; 216 | //获取键盘的高度 217 | NSDictionary *userInfo = [aNotification userInfo]; 218 | NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey]; 219 | CGRect keyboardRect = [aValue CGRectValue]; 220 | int height = keyboardRect.size.height; 221 | _tableBottomConstraint.constant = 44 + height; 222 | UIView *vi = [self.view viewWithTag:100]; 223 | CGRect rec = vi.frame ; 224 | rec.origin.y = _nowHeight - height; 225 | vi.frame = rec; 226 | } 227 | - (void)keyboardWillHide:(NSNotification *)aNotification 228 | { 229 | _ev.hidden = YES; 230 | _tableBottomConstraint.constant = 44; 231 | UIView *vi = [self.view viewWithTag:100]; 232 | vi.frame = CGRectMake(0, _nowHeight, [UIScreen mainScreen].bounds.size.width, 44); 233 | } 234 | - (void)viewDidLayoutSubviews 235 | { 236 | [super viewDidLayoutSubviews]; 237 | UIView *vi = [self.view viewWithTag:100]; 238 | if (!vi) 239 | { 240 | _nowHeight = _tableView.frame.size.height; 241 | [self bottomView]; 242 | } 243 | 244 | } 245 | 246 | #pragma mark - 247 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 248 | { 249 | return _dataArray.count; 250 | } 251 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 252 | { 253 | CSMessageCell *cell=[CSMessageCell cellWithTableView:tableView messageModel:_dataArray[indexPath.row]]; 254 | cell.delegate = self; 255 | // cell 256 | cell.backgroundColor = [[UIColor alloc] initWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1]; 257 | return cell; 258 | } 259 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 260 | { 261 | CSMessageModel *model = _dataArray[indexPath.row]; 262 | return [model cellHeight]; 263 | } 264 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 265 | { 266 | return 0.1; 267 | } 268 | - (void)messageCellSingleClickedWith:(CSMessageCell *)cell 269 | { 270 | 271 | [self.view endEditing:YES]; 272 | 273 | 274 | if (_ev.hidden == NO) 275 | { 276 | _ev.hidden = YES; 277 | _tableBottomConstraint.constant = 44; 278 | UIView *vi = [self.view viewWithTag:100]; 279 | vi.frame = CGRectMake(0, _nowHeight, [UIScreen mainScreen].bounds.size.width, 44); 280 | } 281 | 282 | NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; 283 | CSMessageModel *model = _dataArray[indexPath.row]; 284 | if (model.messageType == MessageTypeVoice) 285 | { 286 | [[CSRecord ShareCSRecord] playRecord]; 287 | 288 | if ([_selectIndex isEqual: indexPath] == NO) 289 | { 290 | 291 | CSMessageCell *cell1 = [self.tableView cellForRowAtIndexPath:_selectIndex]; 292 | [cell1 stopVoiceAnimation]; 293 | 294 | _selectIndex = indexPath; 295 | [cell startVoiceAnimation]; 296 | } 297 | else 298 | { 299 | if (cell.voiceAnimationImageView.isAnimating) 300 | { 301 | [cell stopVoiceAnimation]; 302 | } 303 | else 304 | { 305 | [cell startVoiceAnimation]; 306 | } 307 | } 308 | } 309 | else if (model.messageType == MessageTypeImage) 310 | { 311 | _bigImageView.bigImageView.image = model.imageSmall; 312 | _bigImageView.show = YES; 313 | 314 | // [[UIApplication sharedApplication].keyWindow bringSubviewToFront:_bigImageView]; 315 | } 316 | 317 | } 318 | 319 | -(void)bottomView 320 | { 321 | UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, _nowHeight, [UIScreen mainScreen].bounds.size.width, 44)]; 322 | bgView.tag = 100; 323 | bgView.backgroundColor = [[UIColor alloc] initWithRed:245/255.0 green:245/255.0 blue:245/255.0 alpha:1]; 324 | bgView.layer.masksToBounds = YES; 325 | bgView.layer.borderColor = [[UIColor alloc] initWithRed:235/255.0 green:235/255.0 blue:235/255.0 alpha:1].CGColor; 326 | bgView.layer.borderWidth = 1; 327 | [self.view addSubview:bgView]; 328 | 329 | UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(49, 0, bgView.bounds.size.width - 152, 44)]; 330 | textView.delegate = self; 331 | textView.tag = 101; 332 | textView.returnKeyType = UIReturnKeySend; 333 | textView.font = [UIFont fontWithName:@"PingFangSC-Regular" size:16]; 334 | textView.text = @"hello world"; 335 | [bgView addSubview:textView]; 336 | 337 | 338 | 339 | UIButton *recordBtn = [[UIButton alloc] init]; 340 | recordBtn.frame = CGRectMake(10, 5, 34, 34); 341 | [recordBtn setBackgroundImage:[UIImage imageNamed:@"record"] forState:UIControlStateNormal]; 342 | [recordBtn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside]; 343 | [recordBtn addTarget:self action:@selector(leaveBtnClicked:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside]; 344 | [recordBtn addTarget:self action:@selector(touchDown:)forControlEvents: UIControlEventTouchDragInside]; 345 | [bgView addSubview:recordBtn]; 346 | 347 | UIButton *emojiBtn = [[UIButton alloc] init]; 348 | emojiBtn.frame = CGRectMake(bgView.frame.size.width - 83, 5, 34, 34); 349 | [emojiBtn setBackgroundImage:[UIImage imageNamed:@"emoji"] forState:UIControlStateNormal]; 350 | [emojiBtn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside]; 351 | emojiBtn.tag = 12; 352 | [bgView addSubview:emojiBtn]; 353 | 354 | UIButton *imageBtn = [[UIButton alloc] init]; 355 | imageBtn.frame = CGRectMake(bgView.frame.size.width - 39, 5, 34, 34); 356 | [imageBtn setBackgroundImage:[UIImage imageNamed:@"image"] forState:UIControlStateNormal]; 357 | [imageBtn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside]; 358 | imageBtn.tag = 13; 359 | [bgView addSubview:imageBtn]; 360 | 361 | } 362 | - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{ 363 | if ([text isEqualToString:@"\n"]) 364 | { 365 | if (textView.text.length == 0) 366 | { 367 | return NO; 368 | } 369 | CSMessageModel *model = [[CSMessageModel alloc] init]; 370 | model.showMessageTime=YES; 371 | model.messageSenderType = MessageSenderTypeOther; 372 | model.messageType = MessageTypeText; 373 | model.messageText = textView.text; 374 | model.messageTime = @"16:40"; 375 | [_dataArray addObject:model]; 376 | [_tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForItem:_dataArray.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone]; 377 | [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:_dataArray.count - 1 inSection:0] 378 | animated:YES 379 | scrollPosition:UITableViewScrollPositionMiddle]; 380 | textView.text = @""; 381 | return NO; 382 | } 383 | 384 | return YES; 385 | } 386 | static int iiii = 0; 387 | - (void)touchDown:(UIButton *)btn 388 | { 389 | if (iiii == 0) 390 | { 391 | [[CSRecord ShareCSRecord] beginRecord]; 392 | iiii = 1; 393 | } 394 | 395 | } 396 | - (void)leaveBtnClicked:(UIButton *)btn 397 | { 398 | iiii = 0; 399 | NSLog(@"松开了"); 400 | [[CSRecord ShareCSRecord] endRecord]; 401 | } 402 | - (void)btnClicked:(UIButton *)btn 403 | { 404 | [self.view endEditing:YES]; 405 | _ev.hidden = YES; 406 | _tableBottomConstraint.constant = 44; 407 | UIView *vi = [self.view viewWithTag:100]; 408 | vi.frame = CGRectMake(0, _nowHeight, [UIScreen mainScreen].bounds.size.width, 44); 409 | switch (btn.tag) 410 | { 411 | case 11: 412 | 413 | break; 414 | case 12: 415 | 416 | { 417 | 418 | _ev.hidden = NO; 419 | _tableBottomConstraint.constant = 44 + 180; 420 | UIView *vi = [self.view viewWithTag:100]; 421 | CGRect rec = vi.frame ; 422 | rec.origin.y = _nowHeight - 180; 423 | vi.frame = rec; 424 | 425 | } 426 | 427 | break; 428 | case 13: 429 | { 430 | 431 | 432 | 433 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"请选择" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; 434 | [alertController addAction:[UIAlertAction actionWithTitle:@"相机" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 435 | UIImagePickerController * picker = [[UIImagePickerController alloc]init]; 436 | if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { 437 | 438 | //图片选择是相册(图片来源自相册) 439 | 440 | picker.sourceType = UIImagePickerControllerSourceTypeCamera; 441 | 442 | //设置代理 443 | 444 | picker.delegate=self; 445 | 446 | //模态显示界面 447 | 448 | [self presentViewController:picker animated:YES completion:nil]; 449 | 450 | } 451 | 452 | else { 453 | 454 | NSLog(@"不支持相机"); 455 | 456 | } 457 | 458 | 459 | NSLog(@"点击确认"); 460 | 461 | }]]; 462 | [alertController addAction:[UIAlertAction actionWithTitle:@"相册" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 463 | 464 | UIImagePickerController * picker = [[UIImagePickerController alloc]init]; 465 | if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { 466 | 467 | //图片选择是相册(图片来源自相册) 468 | 469 | picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 470 | 471 | //设置代理 472 | 473 | picker.delegate=self; 474 | 475 | //模态显示界面 476 | 477 | [self presentViewController:picker animated:YES completion:nil]; 478 | 479 | 480 | 481 | } 482 | 483 | NSLog(@"点击确认"); 484 | 485 | }]]; 486 | [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 487 | 488 | [self dismissViewControllerAnimated:YES completion:nil]; 489 | NSLog(@"点击取消"); 490 | 491 | }]]; 492 | 493 | [self presentViewController:alertController animated:YES completion:nil]; 494 | 495 | } 496 | break; 497 | default: 498 | break; 499 | } 500 | NSLog(@"呀!我这个按钮别点击了!"); 501 | } 502 | -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 503 | { 504 | if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary) 505 | { 506 | UIImage * image =info[UIImagePickerControllerOriginalImage]; 507 | CSMessageModel * model = [[CSMessageModel alloc] init]; 508 | model.showMessageTime=YES; 509 | model.messageSenderType = MessageSenderTypeOther; 510 | model.messageType = MessageTypeImage; 511 | model.imageSmall = image; 512 | model.messageTime = @"16:40"; 513 | [_dataArray addObject:model]; 514 | 515 | [_tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForItem:_dataArray.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone]; 516 | [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:_dataArray.count - 1 inSection:0] 517 | animated:YES 518 | scrollPosition:UITableViewScrollPositionMiddle]; 519 | 520 | [self dismissViewControllerAnimated:YES completion:nil]; 521 | } 522 | else if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) 523 | { 524 | UIImage * image =info[UIImagePickerControllerOriginalImage]; 525 | CSMessageModel * model = [[CSMessageModel alloc] init]; 526 | model.showMessageTime=YES; 527 | model.messageSenderType = MessageSenderTypeOther; 528 | model.messageType = MessageTypeImage; 529 | model.imageSmall = image; 530 | model.messageTime = @"16:40"; 531 | [_dataArray addObject:model]; 532 | 533 | [_tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForItem:_dataArray.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone]; 534 | [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:_dataArray.count - 1 inSection:0] 535 | animated:YES 536 | scrollPosition:UITableViewScrollPositionMiddle]; 537 | 538 | [self dismissViewControllerAnimated:YES completion:nil]; 539 | } 540 | } 541 | - (void)showBigImage 542 | { 543 | 544 | } 545 | 546 | #pragma mark - EmojiViewDelegate 547 | - (void)emojiClicked:(NSString *)strEmoji { 548 | UITextView *tv = [self.view viewWithTag:101]; 549 | tv.text = [tv.text stringByAppendingString:strEmoji]; 550 | 551 | } 552 | 553 | - (void)didReceiveMemoryWarning { 554 | [super didReceiveMemoryWarning]; 555 | // Dispose of any resources that can be recreated. 556 | } 557 | 558 | 559 | @end 560 | -------------------------------------------------------------------------------- /ChatHan/dd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/dd.png -------------------------------------------------------------------------------- /ChatHan/ll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/ll.png -------------------------------------------------------------------------------- /ChatHan/m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/m.png -------------------------------------------------------------------------------- /ChatHan/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ChatHan 4 | // 5 | // Created by lee on 2017/12/15. 6 | // Copyright © 2017年 lee. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ChatHan/me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/me.png -------------------------------------------------------------------------------- /ChatHan/mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/mm.png -------------------------------------------------------------------------------- /ChatHan/other.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/other.png -------------------------------------------------------------------------------- /ChatHan/ss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/ss.png -------------------------------------------------------------------------------- /ChatHan/w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanWait/ChatHan/a322db4fa78ea21e7bccd3edac5d8f6b015c573f/ChatHan/w.png -------------------------------------------------------------------------------- /ChatHanTests/ChatHanTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ChatHanTests.m 3 | // ChatHanTests 4 | // 5 | // Created by lee on 2017/12/15. 6 | // Copyright © 2017年 lee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ChatHanTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ChatHanTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /ChatHanTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ChatHanUITests/ChatHanUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ChatHanUITests.m 3 | // ChatHanUITests 4 | // 5 | // Created by lee on 2017/12/15. 6 | // Copyright © 2017年 lee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ChatHanUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ChatHanUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /ChatHanUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | --------------------------------------------------------------------------------