├── .gitignore ├── Podfile ├── README.md ├── VZ.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── VZ.xcworkspace └── contents.xcworkspacedata └── VZ ├── Default-568h@2x.png ├── Default@2x.png ├── Dots@2x.png ├── Icon-120@2x.png ├── Icon.png ├── Icon@2x.png ├── VZ-Info.plist ├── VZ-Prefix.pch ├── VZ.entitlements ├── VZAppDelegate.h ├── VZAppDelegate.m ├── VZCommentCell.h ├── VZCommentCell.m ├── VZFeedbackC.h ├── VZFeedbackC.m ├── VZM.h ├── VZM.m ├── VZMenuC.h ├── VZMenuC.m ├── VZNavC.h ├── VZNavC.m ├── VZNavView.h ├── VZNavView.m ├── VZNearC.h ├── VZNearC.m ├── VZPost.h ├── VZPost.m ├── VZPostActionC.h ├── VZPostActionC.m ├── VZPostCell.h ├── VZPostCell.m ├── VZPostListC.h ├── VZPostListC.m ├── VZPostViewC.h ├── VZPostViewC.m ├── VZProgressView.h ├── VZProgressView.m ├── VZSearchBar.h ├── VZSearchBar.m ├── VZSettingsC.h ├── VZSettingsC.m ├── VZStacView.h ├── VZStacView.m ├── VZStatusListC.h ├── VZStatusListC.m ├── VZWebViewC.h ├── VZWebViewC.m ├── all@2x.png ├── arrow@2x.png ├── bg2@2x.png ├── bg@2x.png ├── chatBg2@2x.png ├── chatBg@2x.png ├── close@2x.png ├── deal.png ├── deal@2x.png ├── en.lproj └── InfoPlist.strings ├── fav.png ├── fav@2x.png ├── geo@2x.png ├── head@2x.png ├── home.png ├── home@2x.png ├── iPhone.storyboard ├── main.m ├── map.png ├── map@2x.png ├── navBg@2x.png ├── near@2x.png ├── pics@2x.png ├── req@2x.png ├── search.png ├── search@2x.png ├── searchClose.png ├── searchClose@2x.png ├── settings@2x.png ├── spam.png ├── spam@2x.png ├── trash.png ├── trash@2x.png └── zh-Hans.lproj └── InfoPlist.strings /.gitignore: -------------------------------------------------------------------------------- 1 | /VZ.xcworkspace/xcshareddata/VZ.xccheckout -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, "5.0" 2 | 3 | target 'VZ' do 4 | pod 'AVOSCloud', :podspec => 'https://download.avoscloud.com/sdk/iOS/current/AVOSCloud.podspec' 5 | pod 'AVOSCloudSNS', :podspec => 'https://download.avoscloud.com/sdk/iOS/current/AVOSCloudSNS.podspec' 6 | 7 | pod 'SIAlertView' 8 | pod 'MMDrawerController' 9 | 10 | end 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 微转 iOS 客户端 2 | 3 | 微转是一个基于微博的数码设备平台, 客户端和后台全部基于AVOSCloud服务实现 4 | 5 | 后台源码地址: [https://github.com/trawor/VZ_Server](https://github.com/trawor/VZ_Server) 6 | 7 | AppStore地址: [https://itunes.apple.com/cn/app/wei-zhuan/id768074220?mt=8](https://itunes.apple.com/cn/app/wei-zhuan/id768074220?mt=8) 8 | 9 | ###我的微博: [@trawor](http://weibo.com/trawor) 10 | 11 | ---- 12 | ###使用方法: 13 | 14 | 1. 安装最新版的CocoaPods 15 | 2. 在项目目录命令行执行 `pod install` 16 | 3. 用Xcode打开workspace文件编译并运行 17 | 18 | ---- 19 | 20 | ###部分截图: 21 | 22 | ![image](http://a2.mzstatic.com/us/r30/Purple6/v4/21/41/90/21419003-2730-71c0-d9bb-383191acabd1/screen568x568.jpeg) 23 | 24 | ![image](http://a5.mzstatic.com/us/r30/Purple/v4/83/b6/4a/83b64ae6-ed48-45e5-957c-09a925bb40e3/screen568x568.jpeg) 25 | 26 | ![image](http://a1.mzstatic.com/us/r30/Purple6/v4/91/ed/ea/91edead0-707a-57e1-9168-279d621a4206/screen568x568.jpeg) 27 | 28 | ![image](http://a2.mzstatic.com/us/r30/Purple/v4/4f/26/f8/4f26f8b8-dffd-becf-c6ef-bc3315214910/screen568x568.jpeg) 29 | 30 | -------------------------------------------------------------------------------- /VZ.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1F043A16187C18CC00EFA890 /* VZWebViewC.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F043A15187C18CC00EFA890 /* VZWebViewC.m */; }; 11 | 1F0F989118385C2E000CE764 /* navBg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1F0F989018385C2E000CE764 /* navBg@2x.png */; }; 12 | 1F0F989418388E0E000CE764 /* VZCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F0F989318388E0E000CE764 /* VZCommentCell.m */; }; 13 | 1F0F98971838987C000CE764 /* chatBg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1F0F98951838987C000CE764 /* chatBg@2x.png */; }; 14 | 1F0F98981838987C000CE764 /* chatBg2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1F0F98961838987C000CE764 /* chatBg2@2x.png */; }; 15 | 1F19022C18ACBC5E00BC5438 /* search.png in Resources */ = {isa = PBXBuildFile; fileRef = 1F19022A18ACBC5E00BC5438 /* search.png */; }; 16 | 1F19022D18ACBC5E00BC5438 /* search@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1F19022B18ACBC5E00BC5438 /* search@2x.png */; }; 17 | 1F19023018ACC66900BC5438 /* VZSearchBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F19022F18ACC66900BC5438 /* VZSearchBar.m */; }; 18 | 1F19023318ACCEC000BC5438 /* searchClose.png in Resources */ = {isa = PBXBuildFile; fileRef = 1F19023118ACCEC000BC5438 /* searchClose.png */; }; 19 | 1F19023418ACCEC000BC5438 /* searchClose@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1F19023218ACCEC000BC5438 /* searchClose@2x.png */; }; 20 | 1F49C110188AB05300767851 /* VZFeedbackC.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F49C10F188AB05300767851 /* VZFeedbackC.m */; }; 21 | 1F4C5C121849B6ED00AB3696 /* VZNavC.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4C5C111849B6ED00AB3696 /* VZNavC.m */; }; 22 | 1F664F8B182375A500DA43F1 /* VZPostViewC.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F664F8A182375A500DA43F1 /* VZPostViewC.m */; }; 23 | 1F7721F11812D3680080308A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F7721F01812D3680080308A /* Foundation.framework */; }; 24 | 1F7721F31812D3680080308A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F7721F21812D3680080308A /* CoreGraphics.framework */; }; 25 | 1F7721F51812D3680080308A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F7721F41812D3680080308A /* UIKit.framework */; }; 26 | 1F7721FB1812D3680080308A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1F7721F91812D3680080308A /* InfoPlist.strings */; }; 27 | 1F7721FD1812D3680080308A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F7721FC1812D3680080308A /* main.m */; }; 28 | 1F7722011812D3680080308A /* VZAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F7722001812D3680080308A /* VZAppDelegate.m */; }; 29 | 1F7722201812D6FC0080308A /* iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1F77221F1812D6FC0080308A /* iPhone.storyboard */; }; 30 | 1F7722241812D7EA0080308A /* VZPostListC.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F7722231812D7EA0080308A /* VZPostListC.m */; }; 31 | 1F772227181383350080308A /* VZMenuC.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F772226181383350080308A /* VZMenuC.m */; }; 32 | 1F7DFD9F1821F31500323B65 /* VZProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F7DFD9E1821F31500323B65 /* VZProgressView.m */; }; 33 | 1F80241118797A80005F4005 /* VZStatusListC.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F80241018797A80005F4005 /* VZStatusListC.m */; }; 34 | 1F8A64BE1838C73D00E825BC /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F8A64BD1838C73D00E825BC /* MapKit.framework */; }; 35 | 1F94FF58183763C0001114B4 /* VZNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F94FF57183763C0001114B4 /* VZNavView.m */; }; 36 | 1F94FF5A183781D5001114B4 /* arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1F94FF59183781D5001114B4 /* arrow@2x.png */; }; 37 | 1F94FF5C183786BA001114B4 /* close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1F94FF5B183786BA001114B4 /* close@2x.png */; }; 38 | 1FAACB231813DB5700BA19DC /* head@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FAACB221813DB5700BA19DC /* head@2x.png */; }; 39 | 1FAACB261813E13F00BA19DC /* near@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FAACB241813E13F00BA19DC /* near@2x.png */; }; 40 | 1FAACB271813E13F00BA19DC /* settings@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FAACB251813E13F00BA19DC /* settings@2x.png */; }; 41 | 1FAACB291813E17F00BA19DC /* pics@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FAACB281813E17F00BA19DC /* pics@2x.png */; }; 42 | 1FAACB2B1813E19700BA19DC /* all@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FAACB2A1813E19700BA19DC /* all@2x.png */; }; 43 | 1FAACB2D1813E1EA00BA19DC /* req@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FAACB2C1813E1EA00BA19DC /* req@2x.png */; }; 44 | 1FAACB2F1813E27B00BA19DC /* Dots@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FAACB2E1813E27B00BA19DC /* Dots@2x.png */; }; 45 | 1FAACB331813E58200BA19DC /* VZM.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FAACB321813E58200BA19DC /* VZM.m */; }; 46 | 1FC0819118252A13005CAFBB /* VZNearC.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FC0819018252A13005CAFBB /* VZNearC.m */; }; 47 | 1FDA867A187926CA00DB536D /* spam.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDA8678187926CA00DB536D /* spam.png */; }; 48 | 1FDA867B187926CA00DB536D /* spam@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDA8679187926CA00DB536D /* spam@2x.png */; }; 49 | 1FDA86841879342800DB536D /* home@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDA86821879342800DB536D /* home@2x.png */; }; 50 | 1FDA86851879342800DB536D /* home.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDA86831879342800DB536D /* home.png */; }; 51 | 1FDD7527181BA4B400F490A3 /* VZPost.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FDD7526181BA4B400F490A3 /* VZPost.m */; }; 52 | 1FDD752A181BAE0600F490A3 /* VZPostCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FDD7529181BAE0600F490A3 /* VZPostCell.m */; }; 53 | 1FDD752C181CCC0700F490A3 /* bg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDD752B181CCC0700F490A3 /* bg@2x.png */; }; 54 | 1FDD752E181CCD6F00F490A3 /* bg2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDD752D181CCD6F00F490A3 /* bg2@2x.png */; }; 55 | 1FDD7530181CE30000F490A3 /* geo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDD752F181CE30000F490A3 /* geo@2x.png */; }; 56 | 1FDF3B11185441CC0069834B /* trash@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDF3B0F185441CC0069834B /* trash@2x.png */; }; 57 | 1FDF3B12185441CC0069834B /* trash.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDF3B10185441CC0069834B /* trash.png */; }; 58 | 1FDF3B151854434D0069834B /* map.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDF3B131854434D0069834B /* map.png */; }; 59 | 1FDF3B161854434D0069834B /* map@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDF3B141854434D0069834B /* map@2x.png */; }; 60 | 1FDF3B19185443D50069834B /* fav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDF3B17185443D50069834B /* fav@2x.png */; }; 61 | 1FDF3B1A185443D50069834B /* fav.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDF3B18185443D50069834B /* fav.png */; }; 62 | 1FDF3B1D185444380069834B /* deal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDF3B1B185444380069834B /* deal@2x.png */; }; 63 | 1FDF3B1E185444380069834B /* deal.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FDF3B1C185444380069834B /* deal.png */; }; 64 | 1FDF3B21185445450069834B /* VZPostActionC.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FDF3B20185445450069834B /* VZPostActionC.m */; }; 65 | 1FE18C55183C983E009E7938 /* VZStacView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FE18C54183C983E009E7938 /* VZStacView.m */; }; 66 | 1FF2A341183B0D3500731771 /* VZSettingsC.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF2A340183B0D3500731771 /* VZSettingsC.m */; }; 67 | 1FFC7EE8188BF79400C16B97 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FFC7EE7188BF79400C16B97 /* Icon.png */; }; 68 | 1FFC7EEA188BF79A00C16B97 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FFC7EE9188BF79A00C16B97 /* Icon@2x.png */; }; 69 | 1FFC7EEC188BF7B200C16B97 /* Icon-120@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FFC7EEB188BF7B200C16B97 /* Icon-120@2x.png */; }; 70 | 1FFC7EEF188BF7DD00C16B97 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FFC7EED188BF7DD00C16B97 /* Default-568h@2x.png */; }; 71 | 1FFC7EF0188BF7DD00C16B97 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FFC7EEE188BF7DD00C16B97 /* Default@2x.png */; }; 72 | 7649AA8F37424D3A8F85BE0C /* libPods-VZ.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 372E87D092FE4BD8BCAD6AB6 /* libPods-VZ.a */; }; 73 | /* End PBXBuildFile section */ 74 | 75 | /* Begin PBXFileReference section */ 76 | 1F043A14187C18CC00EFA890 /* VZWebViewC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZWebViewC.h; sourceTree = ""; }; 77 | 1F043A15187C18CC00EFA890 /* VZWebViewC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZWebViewC.m; sourceTree = ""; }; 78 | 1F0F989018385C2E000CE764 /* navBg@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "navBg@2x.png"; sourceTree = ""; }; 79 | 1F0F989218388E0E000CE764 /* VZCommentCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZCommentCell.h; sourceTree = ""; }; 80 | 1F0F989318388E0E000CE764 /* VZCommentCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZCommentCell.m; sourceTree = ""; }; 81 | 1F0F98951838987C000CE764 /* chatBg@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chatBg@2x.png"; sourceTree = ""; }; 82 | 1F0F98961838987C000CE764 /* chatBg2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chatBg2@2x.png"; sourceTree = ""; }; 83 | 1F19022A18ACBC5E00BC5438 /* search.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = search.png; sourceTree = ""; }; 84 | 1F19022B18ACBC5E00BC5438 /* search@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search@2x.png"; sourceTree = ""; }; 85 | 1F19022E18ACC66900BC5438 /* VZSearchBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZSearchBar.h; sourceTree = ""; }; 86 | 1F19022F18ACC66900BC5438 /* VZSearchBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZSearchBar.m; sourceTree = ""; }; 87 | 1F19023118ACCEC000BC5438 /* searchClose.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = searchClose.png; sourceTree = ""; }; 88 | 1F19023218ACCEC000BC5438 /* searchClose@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "searchClose@2x.png"; sourceTree = ""; }; 89 | 1F49C10E188AB05300767851 /* VZFeedbackC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZFeedbackC.h; sourceTree = ""; }; 90 | 1F49C10F188AB05300767851 /* VZFeedbackC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZFeedbackC.m; sourceTree = ""; }; 91 | 1F4C5C101849B6ED00AB3696 /* VZNavC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZNavC.h; sourceTree = ""; }; 92 | 1F4C5C111849B6ED00AB3696 /* VZNavC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZNavC.m; sourceTree = ""; }; 93 | 1F664F89182375A500DA43F1 /* VZPostViewC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZPostViewC.h; sourceTree = ""; }; 94 | 1F664F8A182375A500DA43F1 /* VZPostViewC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZPostViewC.m; sourceTree = ""; }; 95 | 1F7721ED1812D3680080308A /* VZ.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VZ.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96 | 1F7721F01812D3680080308A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 97 | 1F7721F21812D3680080308A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 98 | 1F7721F41812D3680080308A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 99 | 1F7721F81812D3680080308A /* VZ-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "VZ-Info.plist"; sourceTree = ""; }; 100 | 1F7721FA1812D3680080308A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 101 | 1F7721FC1812D3680080308A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 102 | 1F7721FE1812D3680080308A /* VZ-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VZ-Prefix.pch"; sourceTree = ""; }; 103 | 1F7721FF1812D3680080308A /* VZAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VZAppDelegate.h; sourceTree = ""; }; 104 | 1F7722001812D3680080308A /* VZAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VZAppDelegate.m; sourceTree = ""; }; 105 | 1F77221F1812D6FC0080308A /* iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = iPhone.storyboard; sourceTree = ""; }; 106 | 1F7722221812D7EA0080308A /* VZPostListC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZPostListC.h; sourceTree = ""; }; 107 | 1F7722231812D7EA0080308A /* VZPostListC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZPostListC.m; sourceTree = ""; }; 108 | 1F772225181383350080308A /* VZMenuC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZMenuC.h; sourceTree = ""; }; 109 | 1F772226181383350080308A /* VZMenuC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZMenuC.m; sourceTree = ""; }; 110 | 1F77222818138EE80080308A /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 111 | 1F7DFD9D1821F31500323B65 /* VZProgressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZProgressView.h; sourceTree = ""; }; 112 | 1F7DFD9E1821F31500323B65 /* VZProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZProgressView.m; sourceTree = ""; }; 113 | 1F80240F18797A80005F4005 /* VZStatusListC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZStatusListC.h; sourceTree = ""; }; 114 | 1F80241018797A80005F4005 /* VZStatusListC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZStatusListC.m; sourceTree = ""; }; 115 | 1F8A64BD1838C73D00E825BC /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; 116 | 1F94FF56183763C0001114B4 /* VZNavView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZNavView.h; sourceTree = ""; }; 117 | 1F94FF57183763C0001114B4 /* VZNavView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZNavView.m; sourceTree = ""; }; 118 | 1F94FF59183781D5001114B4 /* arrow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "arrow@2x.png"; sourceTree = ""; }; 119 | 1F94FF5B183786BA001114B4 /* close@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "close@2x.png"; sourceTree = ""; }; 120 | 1FAACB221813DB5700BA19DC /* head@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "head@2x.png"; sourceTree = ""; }; 121 | 1FAACB241813E13F00BA19DC /* near@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "near@2x.png"; sourceTree = ""; }; 122 | 1FAACB251813E13F00BA19DC /* settings@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "settings@2x.png"; sourceTree = ""; }; 123 | 1FAACB281813E17F00BA19DC /* pics@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pics@2x.png"; sourceTree = ""; }; 124 | 1FAACB2A1813E19700BA19DC /* all@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "all@2x.png"; sourceTree = ""; }; 125 | 1FAACB2C1813E1EA00BA19DC /* req@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "req@2x.png"; sourceTree = ""; }; 126 | 1FAACB2E1813E27B00BA19DC /* Dots@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Dots@2x.png"; sourceTree = ""; }; 127 | 1FAACB311813E58200BA19DC /* VZM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZM.h; sourceTree = ""; }; 128 | 1FAACB321813E58200BA19DC /* VZM.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZM.m; sourceTree = ""; }; 129 | 1FC0818F18252A13005CAFBB /* VZNearC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZNearC.h; sourceTree = ""; }; 130 | 1FC0819018252A13005CAFBB /* VZNearC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZNearC.m; sourceTree = ""; }; 131 | 1FDA8678187926CA00DB536D /* spam.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = spam.png; sourceTree = ""; }; 132 | 1FDA8679187926CA00DB536D /* spam@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "spam@2x.png"; sourceTree = ""; }; 133 | 1FDA86821879342800DB536D /* home@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "home@2x.png"; sourceTree = ""; }; 134 | 1FDA86831879342800DB536D /* home.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = home.png; sourceTree = ""; }; 135 | 1FDD7525181BA4B400F490A3 /* VZPost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZPost.h; sourceTree = ""; }; 136 | 1FDD7526181BA4B400F490A3 /* VZPost.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZPost.m; sourceTree = ""; }; 137 | 1FDD7528181BAE0600F490A3 /* VZPostCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZPostCell.h; sourceTree = ""; }; 138 | 1FDD7529181BAE0600F490A3 /* VZPostCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZPostCell.m; sourceTree = ""; }; 139 | 1FDD752B181CCC0700F490A3 /* bg@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "bg@2x.png"; sourceTree = ""; }; 140 | 1FDD752D181CCD6F00F490A3 /* bg2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "bg2@2x.png"; sourceTree = ""; }; 141 | 1FDD752F181CE30000F490A3 /* geo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "geo@2x.png"; sourceTree = ""; }; 142 | 1FDF3B0F185441CC0069834B /* trash@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "trash@2x.png"; sourceTree = ""; }; 143 | 1FDF3B10185441CC0069834B /* trash.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = trash.png; sourceTree = ""; }; 144 | 1FDF3B131854434D0069834B /* map.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = map.png; sourceTree = ""; }; 145 | 1FDF3B141854434D0069834B /* map@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "map@2x.png"; sourceTree = ""; }; 146 | 1FDF3B17185443D50069834B /* fav@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "fav@2x.png"; sourceTree = ""; }; 147 | 1FDF3B18185443D50069834B /* fav.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = fav.png; sourceTree = ""; }; 148 | 1FDF3B1B185444380069834B /* deal@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "deal@2x.png"; sourceTree = ""; }; 149 | 1FDF3B1C185444380069834B /* deal.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = deal.png; sourceTree = ""; }; 150 | 1FDF3B1F185445450069834B /* VZPostActionC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZPostActionC.h; sourceTree = ""; }; 151 | 1FDF3B20185445450069834B /* VZPostActionC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZPostActionC.m; sourceTree = ""; }; 152 | 1FE18C53183C983E009E7938 /* VZStacView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZStacView.h; sourceTree = ""; }; 153 | 1FE18C54183C983E009E7938 /* VZStacView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZStacView.m; sourceTree = ""; }; 154 | 1FF2A33F183B0D3500731771 /* VZSettingsC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VZSettingsC.h; sourceTree = ""; }; 155 | 1FF2A340183B0D3500731771 /* VZSettingsC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VZSettingsC.m; sourceTree = ""; }; 156 | 1FFC7EE7188BF79400C16B97 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; 157 | 1FFC7EE9188BF79A00C16B97 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; 158 | 1FFC7EEB188BF7B200C16B97 /* Icon-120@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-120@2x.png"; sourceTree = ""; }; 159 | 1FFC7EED188BF7DD00C16B97 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 160 | 1FFC7EEE188BF7DD00C16B97 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 161 | 1FFC7EF1188BFEC900C16B97 /* VZ.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = VZ.entitlements; sourceTree = ""; }; 162 | 372E87D092FE4BD8BCAD6AB6 /* libPods-VZ.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VZ.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 163 | 8B4AF051FD3B4904A6F9F111 /* Pods-VZ.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VZ.xcconfig"; path = "Pods/Pods-VZ.xcconfig"; sourceTree = ""; }; 164 | /* End PBXFileReference section */ 165 | 166 | /* Begin PBXFrameworksBuildPhase section */ 167 | 1F7721EA1812D3680080308A /* Frameworks */ = { 168 | isa = PBXFrameworksBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | 1F8A64BE1838C73D00E825BC /* MapKit.framework in Frameworks */, 172 | 1F7721F31812D3680080308A /* CoreGraphics.framework in Frameworks */, 173 | 1F7721F51812D3680080308A /* UIKit.framework in Frameworks */, 174 | 1F7721F11812D3680080308A /* Foundation.framework in Frameworks */, 175 | 7649AA8F37424D3A8F85BE0C /* libPods-VZ.a in Frameworks */, 176 | ); 177 | runOnlyForDeploymentPostprocessing = 0; 178 | }; 179 | /* End PBXFrameworksBuildPhase section */ 180 | 181 | /* Begin PBXGroup section */ 182 | 1F7721E41812D3680080308A = { 183 | isa = PBXGroup; 184 | children = ( 185 | 1F7721F61812D3680080308A /* VZ */, 186 | 1F7721EF1812D3680080308A /* Frameworks */, 187 | 1F7721EE1812D3680080308A /* Products */, 188 | 8B4AF051FD3B4904A6F9F111 /* Pods-VZ.xcconfig */, 189 | ); 190 | sourceTree = ""; 191 | }; 192 | 1F7721EE1812D3680080308A /* Products */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 1F7721ED1812D3680080308A /* VZ.app */, 196 | ); 197 | name = Products; 198 | sourceTree = ""; 199 | }; 200 | 1F7721EF1812D3680080308A /* Frameworks */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 1F8A64BD1838C73D00E825BC /* MapKit.framework */, 204 | 1F7721F01812D3680080308A /* Foundation.framework */, 205 | 1F7721F21812D3680080308A /* CoreGraphics.framework */, 206 | 1F7721F41812D3680080308A /* UIKit.framework */, 207 | 372E87D092FE4BD8BCAD6AB6 /* libPods-VZ.a */, 208 | ); 209 | name = Frameworks; 210 | sourceTree = ""; 211 | }; 212 | 1F7721F61812D3680080308A /* VZ */ = { 213 | isa = PBXGroup; 214 | children = ( 215 | 1F7DFD931821F2F700323B65 /* V */, 216 | 1FAACB301813E56F00BA19DC /* M */, 217 | 1F7722211812D7BF0080308A /* C */, 218 | 1F7721FF1812D3680080308A /* VZAppDelegate.h */, 219 | 1F7722001812D3680080308A /* VZAppDelegate.m */, 220 | 1F7721F71812D3680080308A /* Supporting Files */, 221 | ); 222 | path = VZ; 223 | sourceTree = ""; 224 | }; 225 | 1F7721F71812D3680080308A /* Supporting Files */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | 1FFC7EF1188BFEC900C16B97 /* VZ.entitlements */, 229 | 1FFC7EED188BF7DD00C16B97 /* Default-568h@2x.png */, 230 | 1FFC7EEE188BF7DD00C16B97 /* Default@2x.png */, 231 | 1FFC7EE7188BF79400C16B97 /* Icon.png */, 232 | 1FFC7EE9188BF79A00C16B97 /* Icon@2x.png */, 233 | 1FFC7EEB188BF7B200C16B97 /* Icon-120@2x.png */, 234 | 1F19022A18ACBC5E00BC5438 /* search.png */, 235 | 1F19022B18ACBC5E00BC5438 /* search@2x.png */, 236 | 1F19023118ACCEC000BC5438 /* searchClose.png */, 237 | 1F19023218ACCEC000BC5438 /* searchClose@2x.png */, 238 | 1FDA86821879342800DB536D /* home@2x.png */, 239 | 1FDA86831879342800DB536D /* home.png */, 240 | 1FDA8678187926CA00DB536D /* spam.png */, 241 | 1FDA8679187926CA00DB536D /* spam@2x.png */, 242 | 1FDF3B1B185444380069834B /* deal@2x.png */, 243 | 1FDF3B1C185444380069834B /* deal.png */, 244 | 1FDF3B17185443D50069834B /* fav@2x.png */, 245 | 1FDF3B18185443D50069834B /* fav.png */, 246 | 1FDF3B131854434D0069834B /* map.png */, 247 | 1FDF3B141854434D0069834B /* map@2x.png */, 248 | 1FDF3B0F185441CC0069834B /* trash@2x.png */, 249 | 1FDF3B10185441CC0069834B /* trash.png */, 250 | 1F0F98951838987C000CE764 /* chatBg@2x.png */, 251 | 1F0F98961838987C000CE764 /* chatBg2@2x.png */, 252 | 1F0F989018385C2E000CE764 /* navBg@2x.png */, 253 | 1F94FF5B183786BA001114B4 /* close@2x.png */, 254 | 1F94FF59183781D5001114B4 /* arrow@2x.png */, 255 | 1FAACB2E1813E27B00BA19DC /* Dots@2x.png */, 256 | 1FDD752F181CE30000F490A3 /* geo@2x.png */, 257 | 1FDD752B181CCC0700F490A3 /* bg@2x.png */, 258 | 1FDD752D181CCD6F00F490A3 /* bg2@2x.png */, 259 | 1FAACB2A1813E19700BA19DC /* all@2x.png */, 260 | 1FAACB281813E17F00BA19DC /* pics@2x.png */, 261 | 1FAACB241813E13F00BA19DC /* near@2x.png */, 262 | 1FAACB2C1813E1EA00BA19DC /* req@2x.png */, 263 | 1FAACB251813E13F00BA19DC /* settings@2x.png */, 264 | 1FAACB221813DB5700BA19DC /* head@2x.png */, 265 | 1F77221F1812D6FC0080308A /* iPhone.storyboard */, 266 | 1F7721F81812D3680080308A /* VZ-Info.plist */, 267 | 1F7721F91812D3680080308A /* InfoPlist.strings */, 268 | 1F7721FC1812D3680080308A /* main.m */, 269 | 1F7721FE1812D3680080308A /* VZ-Prefix.pch */, 270 | ); 271 | name = "Supporting Files"; 272 | sourceTree = ""; 273 | }; 274 | 1F7722211812D7BF0080308A /* C */ = { 275 | isa = PBXGroup; 276 | children = ( 277 | 1F0F989218388E0E000CE764 /* VZCommentCell.h */, 278 | 1F0F989318388E0E000CE764 /* VZCommentCell.m */, 279 | 1FDD7528181BAE0600F490A3 /* VZPostCell.h */, 280 | 1FDD7529181BAE0600F490A3 /* VZPostCell.m */, 281 | 1F7722221812D7EA0080308A /* VZPostListC.h */, 282 | 1F7722231812D7EA0080308A /* VZPostListC.m */, 283 | 1F772225181383350080308A /* VZMenuC.h */, 284 | 1F772226181383350080308A /* VZMenuC.m */, 285 | 1F664F89182375A500DA43F1 /* VZPostViewC.h */, 286 | 1F664F8A182375A500DA43F1 /* VZPostViewC.m */, 287 | 1FC0818F18252A13005CAFBB /* VZNearC.h */, 288 | 1FC0819018252A13005CAFBB /* VZNearC.m */, 289 | 1FF2A33F183B0D3500731771 /* VZSettingsC.h */, 290 | 1FF2A340183B0D3500731771 /* VZSettingsC.m */, 291 | 1F4C5C101849B6ED00AB3696 /* VZNavC.h */, 292 | 1F4C5C111849B6ED00AB3696 /* VZNavC.m */, 293 | 1FDF3B1F185445450069834B /* VZPostActionC.h */, 294 | 1FDF3B20185445450069834B /* VZPostActionC.m */, 295 | 1F80240F18797A80005F4005 /* VZStatusListC.h */, 296 | 1F80241018797A80005F4005 /* VZStatusListC.m */, 297 | 1F043A14187C18CC00EFA890 /* VZWebViewC.h */, 298 | 1F043A15187C18CC00EFA890 /* VZWebViewC.m */, 299 | 1F49C10E188AB05300767851 /* VZFeedbackC.h */, 300 | 1F49C10F188AB05300767851 /* VZFeedbackC.m */, 301 | ); 302 | name = C; 303 | sourceTree = ""; 304 | }; 305 | 1F7DFD931821F2F700323B65 /* V */ = { 306 | isa = PBXGroup; 307 | children = ( 308 | 1F7DFD9D1821F31500323B65 /* VZProgressView.h */, 309 | 1F7DFD9E1821F31500323B65 /* VZProgressView.m */, 310 | 1F94FF56183763C0001114B4 /* VZNavView.h */, 311 | 1F94FF57183763C0001114B4 /* VZNavView.m */, 312 | 1FE18C53183C983E009E7938 /* VZStacView.h */, 313 | 1FE18C54183C983E009E7938 /* VZStacView.m */, 314 | 1F19022E18ACC66900BC5438 /* VZSearchBar.h */, 315 | 1F19022F18ACC66900BC5438 /* VZSearchBar.m */, 316 | ); 317 | name = V; 318 | sourceTree = ""; 319 | }; 320 | 1FAACB301813E56F00BA19DC /* M */ = { 321 | isa = PBXGroup; 322 | children = ( 323 | 1FAACB311813E58200BA19DC /* VZM.h */, 324 | 1FAACB321813E58200BA19DC /* VZM.m */, 325 | 1FDD7525181BA4B400F490A3 /* VZPost.h */, 326 | 1FDD7526181BA4B400F490A3 /* VZPost.m */, 327 | ); 328 | name = M; 329 | sourceTree = ""; 330 | }; 331 | /* End PBXGroup section */ 332 | 333 | /* Begin PBXNativeTarget section */ 334 | 1F7721EC1812D3680080308A /* VZ */ = { 335 | isa = PBXNativeTarget; 336 | buildConfigurationList = 1F7722191812D3680080308A /* Build configuration list for PBXNativeTarget "VZ" */; 337 | buildPhases = ( 338 | 6EC9290C8E984A168E3B3944 /* Check Pods Manifest.lock */, 339 | 1F7721E91812D3680080308A /* Sources */, 340 | 1F7721EA1812D3680080308A /* Frameworks */, 341 | 1F7721EB1812D3680080308A /* Resources */, 342 | 8AAD2EFB94384478A691C1DD /* Copy Pods Resources */, 343 | ); 344 | buildRules = ( 345 | ); 346 | dependencies = ( 347 | ); 348 | name = VZ; 349 | productName = VZ; 350 | productReference = 1F7721ED1812D3680080308A /* VZ.app */; 351 | productType = "com.apple.product-type.application"; 352 | }; 353 | /* End PBXNativeTarget section */ 354 | 355 | /* Begin PBXProject section */ 356 | 1F7721E51812D3680080308A /* Project object */ = { 357 | isa = PBXProject; 358 | attributes = { 359 | CLASSPREFIX = VZ; 360 | LastUpgradeCheck = 0500; 361 | ORGANIZATIONNAME = "Plumn LLC."; 362 | TargetAttributes = { 363 | 1F7721EC1812D3680080308A = { 364 | DevelopmentTeam = L8QM6A52NF; 365 | SystemCapabilities = { 366 | com.apple.BackgroundModes = { 367 | enabled = 1; 368 | }; 369 | com.apple.Keychain = { 370 | enabled = 0; 371 | }; 372 | }; 373 | }; 374 | }; 375 | }; 376 | buildConfigurationList = 1F7721E81812D3680080308A /* Build configuration list for PBXProject "VZ" */; 377 | compatibilityVersion = "Xcode 3.2"; 378 | developmentRegion = English; 379 | hasScannedForEncodings = 0; 380 | knownRegions = ( 381 | en, 382 | "zh-Hans", 383 | ); 384 | mainGroup = 1F7721E41812D3680080308A; 385 | productRefGroup = 1F7721EE1812D3680080308A /* Products */; 386 | projectDirPath = ""; 387 | projectRoot = ""; 388 | targets = ( 389 | 1F7721EC1812D3680080308A /* VZ */, 390 | ); 391 | }; 392 | /* End PBXProject section */ 393 | 394 | /* Begin PBXResourcesBuildPhase section */ 395 | 1F7721EB1812D3680080308A /* Resources */ = { 396 | isa = PBXResourcesBuildPhase; 397 | buildActionMask = 2147483647; 398 | files = ( 399 | 1F19022D18ACBC5E00BC5438 /* search@2x.png in Resources */, 400 | 1F19023418ACCEC000BC5438 /* searchClose@2x.png in Resources */, 401 | 1F94FF5C183786BA001114B4 /* close@2x.png in Resources */, 402 | 1F0F98971838987C000CE764 /* chatBg@2x.png in Resources */, 403 | 1FDF3B11185441CC0069834B /* trash@2x.png in Resources */, 404 | 1FDF3B1E185444380069834B /* deal.png in Resources */, 405 | 1FDA867A187926CA00DB536D /* spam.png in Resources */, 406 | 1FAACB2F1813E27B00BA19DC /* Dots@2x.png in Resources */, 407 | 1FFC7EEA188BF79A00C16B97 /* Icon@2x.png in Resources */, 408 | 1FDA86841879342800DB536D /* home@2x.png in Resources */, 409 | 1F19023318ACCEC000BC5438 /* searchClose.png in Resources */, 410 | 1FAACB2B1813E19700BA19DC /* all@2x.png in Resources */, 411 | 1FDA867B187926CA00DB536D /* spam@2x.png in Resources */, 412 | 1F19022C18ACBC5E00BC5438 /* search.png in Resources */, 413 | 1F7721FB1812D3680080308A /* InfoPlist.strings in Resources */, 414 | 1FAACB271813E13F00BA19DC /* settings@2x.png in Resources */, 415 | 1FDD752C181CCC0700F490A3 /* bg@2x.png in Resources */, 416 | 1FFC7EE8188BF79400C16B97 /* Icon.png in Resources */, 417 | 1FAACB261813E13F00BA19DC /* near@2x.png in Resources */, 418 | 1FDF3B161854434D0069834B /* map@2x.png in Resources */, 419 | 1F0F989118385C2E000CE764 /* navBg@2x.png in Resources */, 420 | 1FAACB291813E17F00BA19DC /* pics@2x.png in Resources */, 421 | 1F7722201812D6FC0080308A /* iPhone.storyboard in Resources */, 422 | 1FAACB2D1813E1EA00BA19DC /* req@2x.png in Resources */, 423 | 1F0F98981838987C000CE764 /* chatBg2@2x.png in Resources */, 424 | 1FFC7EEC188BF7B200C16B97 /* Icon-120@2x.png in Resources */, 425 | 1FDF3B1A185443D50069834B /* fav.png in Resources */, 426 | 1FFC7EEF188BF7DD00C16B97 /* Default-568h@2x.png in Resources */, 427 | 1FDF3B1D185444380069834B /* deal@2x.png in Resources */, 428 | 1FAACB231813DB5700BA19DC /* head@2x.png in Resources */, 429 | 1FFC7EF0188BF7DD00C16B97 /* Default@2x.png in Resources */, 430 | 1F94FF5A183781D5001114B4 /* arrow@2x.png in Resources */, 431 | 1FDD752E181CCD6F00F490A3 /* bg2@2x.png in Resources */, 432 | 1FDD7530181CE30000F490A3 /* geo@2x.png in Resources */, 433 | 1FDF3B151854434D0069834B /* map.png in Resources */, 434 | 1FDA86851879342800DB536D /* home.png in Resources */, 435 | 1FDF3B12185441CC0069834B /* trash.png in Resources */, 436 | 1FDF3B19185443D50069834B /* fav@2x.png in Resources */, 437 | ); 438 | runOnlyForDeploymentPostprocessing = 0; 439 | }; 440 | /* End PBXResourcesBuildPhase section */ 441 | 442 | /* Begin PBXShellScriptBuildPhase section */ 443 | 6EC9290C8E984A168E3B3944 /* Check Pods Manifest.lock */ = { 444 | isa = PBXShellScriptBuildPhase; 445 | buildActionMask = 2147483647; 446 | files = ( 447 | ); 448 | inputPaths = ( 449 | ); 450 | name = "Check Pods Manifest.lock"; 451 | outputPaths = ( 452 | ); 453 | runOnlyForDeploymentPostprocessing = 0; 454 | shellPath = /bin/sh; 455 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 456 | showEnvVarsInLog = 0; 457 | }; 458 | 8AAD2EFB94384478A691C1DD /* Copy Pods Resources */ = { 459 | isa = PBXShellScriptBuildPhase; 460 | buildActionMask = 2147483647; 461 | files = ( 462 | ); 463 | inputPaths = ( 464 | ); 465 | name = "Copy Pods Resources"; 466 | outputPaths = ( 467 | ); 468 | runOnlyForDeploymentPostprocessing = 0; 469 | shellPath = /bin/sh; 470 | shellScript = "\"${SRCROOT}/Pods/Pods-VZ-resources.sh\"\n"; 471 | showEnvVarsInLog = 0; 472 | }; 473 | /* End PBXShellScriptBuildPhase section */ 474 | 475 | /* Begin PBXSourcesBuildPhase section */ 476 | 1F7721E91812D3680080308A /* Sources */ = { 477 | isa = PBXSourcesBuildPhase; 478 | buildActionMask = 2147483647; 479 | files = ( 480 | 1FAACB331813E58200BA19DC /* VZM.m in Sources */, 481 | 1FDF3B21185445450069834B /* VZPostActionC.m in Sources */, 482 | 1F0F989418388E0E000CE764 /* VZCommentCell.m in Sources */, 483 | 1FF2A341183B0D3500731771 /* VZSettingsC.m in Sources */, 484 | 1FDD7527181BA4B400F490A3 /* VZPost.m in Sources */, 485 | 1F043A16187C18CC00EFA890 /* VZWebViewC.m in Sources */, 486 | 1FDD752A181BAE0600F490A3 /* VZPostCell.m in Sources */, 487 | 1F4C5C121849B6ED00AB3696 /* VZNavC.m in Sources */, 488 | 1F664F8B182375A500DA43F1 /* VZPostViewC.m in Sources */, 489 | 1F7DFD9F1821F31500323B65 /* VZProgressView.m in Sources */, 490 | 1F772227181383350080308A /* VZMenuC.m in Sources */, 491 | 1F7722241812D7EA0080308A /* VZPostListC.m in Sources */, 492 | 1F7722011812D3680080308A /* VZAppDelegate.m in Sources */, 493 | 1F7721FD1812D3680080308A /* main.m in Sources */, 494 | 1F49C110188AB05300767851 /* VZFeedbackC.m in Sources */, 495 | 1FE18C55183C983E009E7938 /* VZStacView.m in Sources */, 496 | 1FC0819118252A13005CAFBB /* VZNearC.m in Sources */, 497 | 1F94FF58183763C0001114B4 /* VZNavView.m in Sources */, 498 | 1F80241118797A80005F4005 /* VZStatusListC.m in Sources */, 499 | 1F19023018ACC66900BC5438 /* VZSearchBar.m in Sources */, 500 | ); 501 | runOnlyForDeploymentPostprocessing = 0; 502 | }; 503 | /* End PBXSourcesBuildPhase section */ 504 | 505 | /* Begin PBXVariantGroup section */ 506 | 1F7721F91812D3680080308A /* InfoPlist.strings */ = { 507 | isa = PBXVariantGroup; 508 | children = ( 509 | 1F7721FA1812D3680080308A /* en */, 510 | 1F77222818138EE80080308A /* zh-Hans */, 511 | ); 512 | name = InfoPlist.strings; 513 | sourceTree = ""; 514 | }; 515 | /* End PBXVariantGroup section */ 516 | 517 | /* Begin XCBuildConfiguration section */ 518 | 1F7722171812D3680080308A /* Debug */ = { 519 | isa = XCBuildConfiguration; 520 | buildSettings = { 521 | ALWAYS_SEARCH_USER_PATHS = NO; 522 | ARCHS = "$(ARCHS_STANDARD)"; 523 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 524 | CLANG_CXX_LIBRARY = "libc++"; 525 | CLANG_ENABLE_MODULES = YES; 526 | CLANG_ENABLE_OBJC_ARC = YES; 527 | CLANG_WARN_BOOL_CONVERSION = YES; 528 | CLANG_WARN_CONSTANT_CONVERSION = YES; 529 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 530 | CLANG_WARN_EMPTY_BODY = YES; 531 | CLANG_WARN_ENUM_CONVERSION = YES; 532 | CLANG_WARN_INT_CONVERSION = YES; 533 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 534 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 535 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 536 | COPY_PHASE_STRIP = NO; 537 | GCC_C_LANGUAGE_STANDARD = gnu99; 538 | GCC_DYNAMIC_NO_PIC = NO; 539 | GCC_OPTIMIZATION_LEVEL = 0; 540 | GCC_PREPROCESSOR_DEFINITIONS = ( 541 | "DEBUG=1", 542 | "$(inherited)", 543 | ); 544 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 545 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 546 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 547 | GCC_WARN_UNDECLARED_SELECTOR = YES; 548 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 549 | GCC_WARN_UNUSED_FUNCTION = YES; 550 | GCC_WARN_UNUSED_VARIABLE = YES; 551 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 552 | ONLY_ACTIVE_ARCH = YES; 553 | SDKROOT = iphoneos; 554 | }; 555 | name = Debug; 556 | }; 557 | 1F7722181812D3680080308A /* Release */ = { 558 | isa = XCBuildConfiguration; 559 | buildSettings = { 560 | ALWAYS_SEARCH_USER_PATHS = NO; 561 | ARCHS = "$(ARCHS_STANDARD)"; 562 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 563 | CLANG_CXX_LIBRARY = "libc++"; 564 | CLANG_ENABLE_MODULES = YES; 565 | CLANG_ENABLE_OBJC_ARC = YES; 566 | CLANG_WARN_BOOL_CONVERSION = YES; 567 | CLANG_WARN_CONSTANT_CONVERSION = YES; 568 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 569 | CLANG_WARN_EMPTY_BODY = YES; 570 | CLANG_WARN_ENUM_CONVERSION = YES; 571 | CLANG_WARN_INT_CONVERSION = YES; 572 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 573 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 574 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 575 | COPY_PHASE_STRIP = YES; 576 | ENABLE_NS_ASSERTIONS = NO; 577 | GCC_C_LANGUAGE_STANDARD = gnu99; 578 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 579 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 580 | GCC_WARN_UNDECLARED_SELECTOR = YES; 581 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 582 | GCC_WARN_UNUSED_FUNCTION = YES; 583 | GCC_WARN_UNUSED_VARIABLE = YES; 584 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 585 | SDKROOT = iphoneos; 586 | VALIDATE_PRODUCT = YES; 587 | }; 588 | name = Release; 589 | }; 590 | 1F77221A1812D3680080308A /* Debug */ = { 591 | isa = XCBuildConfiguration; 592 | baseConfigurationReference = 8B4AF051FD3B4904A6F9F111 /* Pods-VZ.xcconfig */; 593 | buildSettings = { 594 | APS_ENV = development; 595 | ARCHS = "$(ARCHS_STANDARD)"; 596 | CODE_SIGN_ENTITLEMENTS = VZ/VZ.entitlements; 597 | CODE_SIGN_IDENTITY = ""; 598 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 599 | COMPRESS_PNG_FILES = NO; 600 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 601 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 602 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 603 | GCC_PREFIX_HEADER = "VZ/VZ-Prefix.pch"; 604 | INFOPLIST_FILE = "VZ/VZ-Info.plist"; 605 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 606 | PRODUCT_NAME = "$(TARGET_NAME)"; 607 | PROVISIONING_PROFILE = "E398A816-F7A1-43A1-9A39-2DC583B4B447"; 608 | TASK_ALLOW = YES; 609 | VALID_ARCHS = "armv7 armv7s arm64"; 610 | WRAPPER_EXTENSION = app; 611 | }; 612 | name = Debug; 613 | }; 614 | 1F77221B1812D3680080308A /* Release */ = { 615 | isa = XCBuildConfiguration; 616 | baseConfigurationReference = 8B4AF051FD3B4904A6F9F111 /* Pods-VZ.xcconfig */; 617 | buildSettings = { 618 | APS_ENV = production; 619 | ARCHS = "$(ARCHS_STANDARD)"; 620 | CODE_SIGN_ENTITLEMENTS = VZ/VZ.entitlements; 621 | CODE_SIGN_IDENTITY = ""; 622 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 623 | COMPRESS_PNG_FILES = NO; 624 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 625 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 626 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 627 | GCC_PREFIX_HEADER = "VZ/VZ-Prefix.pch"; 628 | INFOPLIST_FILE = "VZ/VZ-Info.plist"; 629 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 630 | PRODUCT_NAME = "$(TARGET_NAME)"; 631 | PROVISIONING_PROFILE = "40959762-2D45-45E8-92F5-D97CD6953E82"; 632 | TASK_ALLOW = NO; 633 | WRAPPER_EXTENSION = app; 634 | }; 635 | name = Release; 636 | }; 637 | /* End XCBuildConfiguration section */ 638 | 639 | /* Begin XCConfigurationList section */ 640 | 1F7721E81812D3680080308A /* Build configuration list for PBXProject "VZ" */ = { 641 | isa = XCConfigurationList; 642 | buildConfigurations = ( 643 | 1F7722171812D3680080308A /* Debug */, 644 | 1F7722181812D3680080308A /* Release */, 645 | ); 646 | defaultConfigurationIsVisible = 0; 647 | defaultConfigurationName = Release; 648 | }; 649 | 1F7722191812D3680080308A /* Build configuration list for PBXNativeTarget "VZ" */ = { 650 | isa = XCConfigurationList; 651 | buildConfigurations = ( 652 | 1F77221A1812D3680080308A /* Debug */, 653 | 1F77221B1812D3680080308A /* Release */, 654 | ); 655 | defaultConfigurationIsVisible = 0; 656 | defaultConfigurationName = Release; 657 | }; 658 | /* End XCConfigurationList section */ 659 | }; 660 | rootObject = 1F7721E51812D3680080308A /* Project object */; 661 | } 662 | -------------------------------------------------------------------------------- /VZ.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VZ.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /VZ/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/Default-568h@2x.png -------------------------------------------------------------------------------- /VZ/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/Default@2x.png -------------------------------------------------------------------------------- /VZ/Dots@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/Dots@2x.png -------------------------------------------------------------------------------- /VZ/Icon-120@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/Icon-120@2x.png -------------------------------------------------------------------------------- /VZ/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/Icon.png -------------------------------------------------------------------------------- /VZ/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/Icon@2x.png -------------------------------------------------------------------------------- /VZ/VZ-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIcons 12 | 13 | CFBundlePrimaryIcon 14 | 15 | CFBundleIconFiles 16 | 17 | Icon-120 18 | 19 | 20 | 21 | CFBundleIdentifier 22 | com.plumn.vz 23 | CFBundleInfoDictionaryVersion 24 | 6.0 25 | CFBundleName 26 | ${PRODUCT_NAME} 27 | CFBundlePackageType 28 | APPL 29 | CFBundleShortVersionString 30 | 1.1 31 | CFBundleSignature 32 | ???? 33 | CFBundleURLTypes 34 | 35 | 36 | CFBundleTypeRole 37 | Viewer 38 | CFBundleURLName 39 | weibocallback 40 | CFBundleURLSchemes 41 | 42 | sinaweibosso.2858658895 43 | 44 | 45 | 46 | CFBundleVersion 47 | 1.1 48 | LSRequiresIPhoneOS 49 | 50 | UIBackgroundModes 51 | 52 | fetch 53 | 54 | UIPrerenderedIcon 55 | 56 | UIRequiredDeviceCapabilities 57 | 58 | armv7 59 | 60 | UIStatusBarHidden 61 | 62 | UISupportedInterfaceOrientations 63 | 64 | UIInterfaceOrientationPortrait 65 | 66 | UIViewControllerBasedStatusBarAppearance 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /VZ/VZ-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #import 17 | #import 18 | #endif 19 | -------------------------------------------------------------------------------- /VZ/VZ.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | get-task-allow 6 | 7 | aps-environment 8 | $(APS_ENV) 9 | 10 | 11 | -------------------------------------------------------------------------------- /VZ/VZAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZAppDelegate.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-19. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface VZAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | 17 | 18 | -------------------------------------------------------------------------------- /VZ/VZAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZAppDelegate.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-19. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZAppDelegate.h" 10 | #import 11 | 12 | #import "VZMenuC.h" 13 | #import "VZM.h" 14 | 15 | #import 16 | #import "VZNavView.h" 17 | 18 | 19 | @interface VZAppDelegate() 20 | { 21 | 22 | } 23 | @end 24 | 25 | @implementation VZAppDelegate 26 | 27 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 28 | { 29 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 30 | 31 | [[UINavigationBar appearance] setBackgroundImage:[[UIImage imageNamed:@"navBg"] stretchableImageWithLeftCapWidth:25 topCapHeight:1] forBarMetrics:UIBarMetricsDefault]; 32 | 33 | [[UINavigationBar appearance] setTitleTextAttributes:@{ 34 | UITextAttributeTextColor:[UIColor whiteColor] 35 | }]; 36 | 37 | [[UIBarButtonItem appearance] setTitleTextAttributes:@{ 38 | UITextAttributeTextColor:[UIColor whiteColor] 39 | } forState:UIControlStateNormal]; 40 | [[UIBarButtonItem appearance] setTintColor:[UIColor whiteColor]]; 41 | [[UIBarButtonItem appearance] setBackgroundImage:[UIImage new] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 42 | 43 | if (is7orLater()) { 44 | [[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"arrow"]]; 45 | [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"arrow"]]; 46 | 47 | [UIBarButtonItem.appearance setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -64) forBarMetrics:UIBarMetricsDefault]; 48 | 49 | self.window.tintColor = [UIColor whiteColor]; 50 | 51 | }else{ 52 | [[UIBarButtonItem appearance] setBackButtonBackgroundImage:[[UIImage imageNamed:@"arrow"] stretchableImageWithLeftCapWidth:16 topCapHeight:0] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 53 | } 54 | 55 | 56 | model; 57 | 58 | self.window.backgroundColor=[UIColor blackColor]; 59 | 60 | UIImageView *bg=[[UIImageView alloc] initWithImage:[VZTheme bgImage]]; 61 | bg.alpha=0.8; 62 | [self.window addSubview:bg]; 63 | 64 | [AVOSCloud setApplicationId:@"1tglhmgzoq6apby1rmhx3fc5kg2ie0bums7085d3cqhpunlo" 65 | clientKey:@"4es7zmmqsx0xarkp7svkwady8eaipwdz83c2mccoi0z15358"]; 66 | 67 | [AVOSCloud setLastModifyEnabled:YES]; 68 | [AVAnalytics setCrashReportEnabled:YES]; 69 | 70 | 71 | UIStoryboard *board=[UIStoryboard storyboardWithName:@"iPhone" bundle:Nil]; 72 | 73 | VZMenuC *menuC=[board instantiateViewControllerWithIdentifier:@"menuC"]; 74 | 75 | 76 | UINavigationController *nav=[board instantiateInitialViewController]; 77 | 78 | if ([nav respondsToSelector:@selector(interactivePopGestureRecognizer)]) { 79 | nav.interactivePopGestureRecognizer.enabled=YES; 80 | } 81 | 82 | MMDrawerController * menu = [[MMDrawerController alloc]initWithCenterViewController:nav 83 | leftDrawerViewController:menuC]; 84 | 85 | 86 | menu.openDrawerGestureModeMask=MMOpenDrawerGestureModeNone; 87 | menu.closeDrawerGestureModeMask=MMCloseDrawerGestureModeTapCenterView; 88 | menu.shouldStretchDrawer=YES; 89 | menu.maximumLeftDrawerWidth=64; 90 | 91 | menu.maximumRightDrawerWidth=64; 92 | 93 | self.window.rootViewController=menu; 94 | menu.view.backgroundColor=[UIColor clearColor]; 95 | [self.window makeKeyAndVisible]; 96 | 97 | 98 | #if !TARGET_IPHONE_SIMULATOR 99 | [application registerForRemoteNotificationTypes: 100 | UIRemoteNotificationTypeBadge | 101 | UIRemoteNotificationTypeAlert | 102 | UIRemoteNotificationTypeSound]; 103 | #endif 104 | 105 | return YES; 106 | } 107 | 108 | - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 109 | AVInstallation *currentInstallation = [AVInstallation currentInstallation]; 110 | [currentInstallation setDeviceTokenFromData:deviceToken]; 111 | 112 | NSMutableArray *channels=[NSMutableArray arrayWithArray:currentInstallation.channels]; 113 | if (![channels containsObject:@"update"]) {// 设置默认的推送 114 | [channels addObject:@"update"]; 115 | currentInstallation.channels=channels; 116 | [currentInstallation saveInBackground]; 117 | } 118 | } 119 | 120 | -(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{ 121 | 122 | [AVAnalytics event:@"开启推送失败" label:[error description]]; 123 | 124 | } 125 | 126 | -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{ 127 | [AVAnalytics trackAppOpenedWithRemoteNotificationPayload:nil]; 128 | } 129 | 130 | -(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{ 131 | return [AVOSCloudSNS handleOpenURL:url]; 132 | } 133 | 134 | - (void)applicationWillEnterForeground:(UIApplication *)application 135 | { 136 | application.applicationIconBadgeNumber=0; 137 | } 138 | 139 | - (void)applicationDidBecomeActive:(UIApplication *)application 140 | { 141 | // 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. 142 | } 143 | 144 | - (void)applicationWillTerminate:(UIApplication *)application 145 | { 146 | application.applicationIconBadgeNumber=0; 147 | } 148 | 149 | @end 150 | -------------------------------------------------------------------------------- /VZ/VZCommentCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZCommentCell.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-17. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface VZCommentCell : UITableViewCell 12 | @property (weak, nonatomic) IBOutlet UIImageView *avatarView; 13 | @property (weak, nonatomic) IBOutlet UILabel *textLb; 14 | @property (weak, nonatomic) IBOutlet UIImageView *textBg; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /VZ/VZCommentCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZCommentCell.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-17. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZCommentCell.h" 10 | #import 11 | #import "VZM.h" 12 | @implementation VZCommentCell 13 | 14 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 15 | { 16 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 17 | if (self) { 18 | // Initialization code 19 | } 20 | return self; 21 | } 22 | 23 | -(void)awakeFromNib{ 24 | self.avatarView.layer.borderWidth =1; 25 | self.avatarView.layer.borderColor=[UIColor whiteColor].CGColor; 26 | self.avatarView.layer.cornerRadius=20; 27 | self.avatarView.clipsToBounds=YES; 28 | 29 | self.textLb.textColor=[VZTheme textColor]; 30 | } 31 | 32 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated 33 | { 34 | [super setSelected:selected animated:animated]; 35 | 36 | } 37 | 38 | -(void)layoutSubviews{ 39 | [super layoutSubviews]; 40 | 41 | NSString *text=self.textLb.text; 42 | if (text.length>0) { 43 | CGSize size= [text sizeWithFont:self.textLb.font constrainedToSize:CGSizeMake(220, 500)]; 44 | CGRect f=self.textLb.frame; 45 | f.size=size; 46 | 47 | 48 | CGRect f2=self.textBg.frame; 49 | 50 | //float x1=self.frame.size.width-f2.origin.x-f2.size.width; 51 | float w=f2.size.width; 52 | 53 | f2.size=CGSizeMake(size.width+30, MAX(size.height+25, 39)); 54 | 55 | if ([self.reuseIdentifier isEqualToString:@"CommentCell2"]) { 56 | f.origin.x-=f2.size.width-w; 57 | f2.origin.x-=f2.size.width-w; 58 | } 59 | 60 | self.textLb.frame=f; 61 | self.textBg.frame=f2; 62 | } 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /VZ/VZFeedbackC.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZFeedbackC.h 3 | // VZ 4 | // 5 | // Created by Travis on 14-1-18. 6 | // Copyright (c) 2014年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "VZM.h" 11 | @interface VZFeedbackC : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /VZ/VZFeedbackC.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZFeedbackC.m 3 | // VZ 4 | // 5 | // Created by Travis on 14-1-18. 6 | // Copyright (c) 2014年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZFeedbackC.h" 10 | #import 11 | @interface AVAnalyticsUtils : NSObject 12 | 13 | +(NSMutableDictionary *)deviceInfo; 14 | 15 | @end 16 | 17 | @interface VZFeedbackC () 18 | @property(nonatomic,weak) IBOutlet UITextView *textView; 19 | @end 20 | 21 | @implementation VZFeedbackC 22 | 23 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 24 | { 25 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 26 | if (self) { 27 | // Custom initialization 28 | } 29 | return self; 30 | } 31 | 32 | -(IBAction)send:(id)a{ 33 | if (self.textView.text.length<6) { 34 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"提示" andMessage:@"请您再多说几句吧"]; 35 | 36 | [alertView addButtonWithTitle:@"确定" 37 | type:SIAlertViewButtonTypeDefault 38 | handler:^(SIAlertView *alert) { 39 | 40 | }]; 41 | 42 | alertView.transitionStyle = SIAlertViewTransitionStyleDropDown; 43 | 44 | [alertView show]; 45 | }else{ 46 | [self.textView resignFirstResponder]; 47 | self.view.userInteractionEnabled=NO; 48 | 49 | AVObject *fb=[AVObject objectWithClassName:@"Feedback"]; 50 | if ([VZUser currentUser]) { 51 | [fb setObject:[VZUser currentUser] forKey:@"from"]; 52 | } 53 | 54 | [fb setObject:[AVAnalyticsUtils deviceInfo] forKey:@"deviceInfo"]; 55 | 56 | [fb setObject:self.textView.text forKey:@"text"]; 57 | 58 | __weak typeof(self) ws=self; 59 | [fb saveEventually:^(BOOL succeeded, NSError *error) { 60 | ws.view.userInteractionEnabled=YES; 61 | 62 | NSString *title=succeeded?@"发送成功":@"发送失败"; 63 | 64 | NSString *msg=succeeded?@"谢谢您的反馈,这对我们非常重要.":[error.userInfo objectForKey:NSLocalizedDescriptionKey]; 65 | 66 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:title andMessage:msg]; 67 | 68 | if (succeeded) { 69 | [alertView addButtonWithTitle:@"确定" 70 | type:SIAlertViewButtonTypeDefault 71 | handler:^(SIAlertView *alert) { 72 | [ws.navigationController popToRootViewControllerAnimated:YES]; 73 | }]; 74 | }else{ 75 | [alertView addButtonWithTitle:@"重试" 76 | type:SIAlertViewButtonTypeDefault 77 | handler:^(SIAlertView *alert) { 78 | [ws send:Nil]; 79 | }]; 80 | [alertView addButtonWithTitle:@"取消" 81 | type:SIAlertViewButtonTypeCancel 82 | handler:^(SIAlertView *alert) { 83 | [ws.navigationController popToRootViewControllerAnimated:YES]; 84 | }]; 85 | 86 | } 87 | 88 | 89 | 90 | alertView.transitionStyle = SIAlertViewTransitionStyleDropDown; 91 | 92 | [alertView show]; 93 | }]; 94 | } 95 | } 96 | 97 | -(void)viewWillAppear:(BOOL)animated{ 98 | [super viewWillAppear:animated]; 99 | [self.textView becomeFirstResponder]; 100 | [AVAnalytics beginLogPageView:@"意见反馈"]; 101 | } 102 | 103 | -(void)viewWillDisappear:(BOOL)animated{ 104 | [super viewWillDisappear:animated]; 105 | [AVAnalytics endLogPageView:@"意见反馈"]; 106 | } 107 | 108 | - (void)viewDidLoad 109 | { 110 | [super viewDidLoad]; 111 | self.view.backgroundColor=[UIColor colorWithPatternImage:[VZTheme bgImage]]; 112 | } 113 | 114 | - (void)didReceiveMemoryWarning 115 | { 116 | [super didReceiveMemoryWarning]; 117 | // Dispose of any resources that can be recreated. 118 | } 119 | 120 | /* 121 | #pragma mark - Navigation 122 | 123 | // In a storyboard-based application, you will often want to do a little preparation before navigation 124 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 125 | { 126 | // Get the new view controller using [segue destinationViewController]. 127 | // Pass the selected object to the new view controller. 128 | } 129 | */ 130 | 131 | @end 132 | -------------------------------------------------------------------------------- /VZ/VZM.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZM.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-20. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "VZPost.h" 11 | 12 | #import 13 | 14 | #import 15 | #import 16 | 17 | #import 18 | 19 | BOOL is7orLater(); 20 | 21 | typedef enum{ 22 | VZThemeTypeModern =0, 23 | VZThemeTypeLight 24 | } VZThemeType; 25 | 26 | @interface VZTheme: NSObject 27 | +(void)changeTheme:(VZThemeType)theme; 28 | +(UIColor *)textColor; 29 | +(UIColor *)bgColor; 30 | +(UIImage*)bgImage; 31 | @end 32 | 33 | 34 | @interface VZM : NSObject 35 | 36 | @property(nonatomic,assign) BOOL showAroundOnly; 37 | 38 | @property(nonatomic,assign) BOOL showPostsWithPicsOnly; 39 | @property(nonatomic,assign) VZThemeType theme; 40 | 41 | @property(nonatomic,retain) AVHTTPClient *client; 42 | 43 | +(VZM*)shared; 44 | 45 | +(NSString*)storeIdOfURL:(NSString*)url; 46 | 47 | -(void)login:(AVUserResultBlock)callback; 48 | -(void)logout; 49 | 50 | -(void)getCommentWithWbid:(NSString*)wbid callback:(AVArrayResultBlock)callback; 51 | -(void)commentToWbid:(NSString*)wbid toCommentId:(NSString*)cid withText:(NSString*)text callback:(AVSNSResultBlock)callback; 52 | 53 | -(void)uploadImage:(UIImage*)image callback:(AVSNSResultBlock)callback; 54 | @end 55 | 56 | #define model [VZM shared] 57 | 58 | 59 | @interface VZUser : AVUser 60 | 61 | @property(nonatomic,copy) NSString *avatar; 62 | @property(nonatomic,readonly) NSString *wbid; 63 | -(NSString*)wbid; 64 | 65 | 66 | /** 67 | * 查找来着微博的好友 68 | * 69 | * @param callback 回调返回好友ID数字 70 | */ 71 | -(void)findMyFriendOnWeibo:(AVArrayResultBlock)callback; 72 | 73 | -(void)watch:(BOOL)flat post:(VZPost*)post callback:(AVBooleanResultBlock)callback; 74 | @end -------------------------------------------------------------------------------- /VZ/VZM.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZM.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-20. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZM.h" 10 | #import 11 | #import 12 | 13 | BOOL is7orLater(){ 14 | static int sysVersion=0; 15 | if (sysVersion==0) { 16 | sysVersion=[[[[UIDevice currentDevice] systemVersion] substringToIndex:1] integerValue]; 17 | } 18 | 19 | 20 | return sysVersion>=7; 21 | }; 22 | 23 | @implementation VZTheme 24 | +(void)changeTheme:(VZThemeType)theme{ 25 | model.theme=theme; 26 | [[NSUserDefaults standardUserDefaults] setInteger:theme forKey:@"Theme"]; 27 | [[NSUserDefaults standardUserDefaults] synchronize]; 28 | } 29 | +(UIColor *)textColor{ 30 | switch(model.theme){ 31 | case VZThemeTypeLight: 32 | return [UIColor lightTextColor]; 33 | case VZThemeTypeModern: 34 | return [UIColor whiteColor]; 35 | } 36 | return nil; 37 | } 38 | +(UIColor *)bgColor{ 39 | switch(model.theme){ 40 | case VZThemeTypeLight: 41 | return [UIColor lightTextColor]; 42 | case VZThemeTypeModern: 43 | return [UIColor clearColor]; 44 | } 45 | return nil; 46 | } 47 | 48 | +(UIImage*)bgImage{ 49 | switch(model.theme){ 50 | case VZThemeTypeLight: 51 | return [UIImage imageNamed:@"bg"]; 52 | case VZThemeTypeModern: 53 | return [UIImage imageNamed:@"bg2"]; 54 | } 55 | return nil; 56 | } 57 | 58 | @end 59 | 60 | @implementation VZM 61 | +(VZM*)shared{ 62 | #ifdef DEBUG 63 | setenv("LOG_CURL", "1", 0); 64 | #endif 65 | 66 | static VZM *_vzm_=Nil; 67 | if (_vzm_==Nil) { 68 | _vzm_=[VZM new]; 69 | } 70 | return _vzm_; 71 | } 72 | +(NSString*)storeIdOfURL:(NSString *)url{ 73 | if ([url rangeOfString:@"itunes.apple.com"].length) { 74 | NSRegularExpression *re=[NSRegularExpression regularExpressionWithPattern:@"id([0-9]{8,})" options:0 error:nil]; 75 | NSTextCheckingResult *result= [re firstMatchInString:url options:NSMatchingReportCompletion range:NSMakeRange(0, url.length)]; 76 | 77 | if (result) { 78 | NSString *storeId=[url substringWithRange:[result rangeAtIndex:1]]; 79 | return storeId; 80 | } 81 | } 82 | 83 | return nil; 84 | } 85 | 86 | - (id)init 87 | { 88 | self = [super init]; 89 | if (self) { 90 | [VZPost registerSubclass]; 91 | [VZUser registerSubclass]; 92 | 93 | self.theme=[[NSUserDefaults standardUserDefaults] integerForKey:@"Theme"]; 94 | 95 | AVHTTPClient *client=[[AVHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://vz.avosapps.com"]]; 96 | self.client=client; 97 | } 98 | return self; 99 | } 100 | -(void)login:(AVUserResultBlock)callback{ 101 | [AVOSCloudSNS setupPlatform:AVOSCloudSNSSinaWeibo withAppKey:@"2858658895" andAppSecret:@"9d97c1cce2893cbdcdc970f05bc55fe4" andRedirectURI:@"http://vz.avosapps.com/oauth?type=weibo"]; 102 | //[AVOSCloudSNS setupPlatform:AVOSCloudSNSSinaWeibo withAppKey:@"31024382" andAppSecret:@"25c3e6b5763653d1e5b280884b45c51f" andRedirectURI:@"http://"]; 103 | 104 | [AVOSCloudSNS loginWithCallback:^(NSDictionary* object, NSError *error) { 105 | if (error==nil && object) { 106 | [VZUser loginWithAuthData:object block:^(AVUser *user, NSError *error) { 107 | BOOL needSave=NO; 108 | if (![user objectForKey:@"avatar"]) { 109 | [user setObject:object[@"avatar"] forKey:@"avatar"]; 110 | needSave=YES; 111 | } 112 | 113 | if (![user objectForKey:@"name"]) { 114 | [user setObject:object[@"username"] forKey:@"name"]; 115 | needSave=YES; 116 | } 117 | if (needSave) { 118 | [user save]; 119 | } 120 | 121 | AVInstallation *currentInstallation = [AVInstallation currentInstallation]; 122 | if (currentInstallation.deviceToken) { 123 | [currentInstallation setObject:user forKey:@"user"]; 124 | [currentInstallation saveInBackground]; 125 | } 126 | 127 | 128 | callback(user,error); 129 | }]; 130 | } 131 | 132 | } toPlatform:AVOSCloudSNSSinaWeibo]; 133 | 134 | [AVAnalytics event:@"用户登陆"]; 135 | } 136 | 137 | -(void)logout{ 138 | [AVUser logOut]; 139 | 140 | NSDictionary *dict= [AVOSCloudSNS userInfo:AVOSCloudSNSSinaWeibo]; 141 | NSString *token=[dict objectForKey:@"access_token"]; 142 | 143 | [model.client getPath:@"https://api.weibo.com/oauth2/revokeoauth2" parameters:@{@"access_token":token} success:^(AVHTTPRequestOperation *operation, id responseObject) { 144 | NSLog(@"success"); 145 | } failure:^(AVHTTPRequestOperation *operation, NSError *error) { 146 | NSLog(@"logout error %@",[error description]); 147 | }]; 148 | 149 | [AVOSCloudSNS logout:AVOSCloudSNSSinaWeibo]; 150 | 151 | AVInstallation *currentInstallation = [AVInstallation currentInstallation]; 152 | if ([currentInstallation objectForKey:@"user"]) { 153 | [currentInstallation removeObjectForKey:@"user"]; 154 | [currentInstallation saveInBackground]; 155 | } 156 | 157 | [AVAnalytics event:@"用户注销"]; 158 | } 159 | 160 | -(void)getCommentWithWbid:(NSString*)wbid callback:(AVArrayResultBlock)callback{ 161 | if (![AVOSCloudSNS doesUserExpireOfPlatform:AVOSCloudSNSSinaWeibo]) { 162 | NSDictionary *dict= [AVOSCloudSNS userInfo:AVOSCloudSNSSinaWeibo]; 163 | NSString *token=[dict objectForKey:@"access_token"]; 164 | 165 | NSString *url=[NSString stringWithFormat:@"https://api.weibo.com/2/comments/show.json?id=%@&access_token=%@",wbid,token]; 166 | NSURLRequest *req=[NSURLRequest requestWithURL:[NSURL URLWithString:url]]; 167 | 168 | AVJSONRequestOperation *opt=[AVJSONRequestOperation JSONRequestOperationWithRequest:req success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 169 | NSArray *arr= JSON[@"comments"]; 170 | if (arr) { 171 | NSArray *shuma=@[@"2043408047",@"1761596064",@"1882458640",@"1841288857",@"3787475667",@"3701452524"]; 172 | 173 | NSMutableArray *a=[NSMutableArray array]; 174 | 175 | for (NSDictionary *comment in arr) { 176 | NSString *idstr=comment[@"user"][@"idstr"]; 177 | if ([shuma containsObject:idstr]) { 178 | continue; 179 | } 180 | 181 | [a addObject:comment]; 182 | } 183 | 184 | [a sortUsingDescriptors:@[[[NSSortDescriptor alloc] initWithKey:@"idstr" ascending:YES]]]; 185 | callback(a,nil); 186 | }else{ 187 | callback(Nil,Nil); 188 | } 189 | 190 | } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 191 | callback(Nil,error); 192 | NSLog(@"%@", [error description]); 193 | }]; 194 | 195 | [self.client enqueueHTTPRequestOperation:opt]; 196 | }else{ 197 | callback(nil,[NSError errorWithDomain:@"vz" code:1 userInfo:nil]); 198 | } 199 | 200 | } 201 | 202 | -(void)commentToWbid:(NSString*)wbid toCommentId:(NSString*)cid withText:(NSString*)text callback:(AVSNSResultBlock)callback{ 203 | if (![AVOSCloudSNS doesUserExpireOfPlatform:AVOSCloudSNSSinaWeibo]) { 204 | NSDictionary *dict= [AVOSCloudSNS userInfo:AVOSCloudSNSSinaWeibo]; 205 | NSString *token=[dict objectForKey:@"access_token"]; 206 | 207 | NSString *url=[NSString stringWithFormat:@"https://api.weibo.com/2/comments/%@.json",cid?@"reply":@"create"]; 208 | 209 | NSMutableDictionary *param=[NSMutableDictionary dictionary]; 210 | [param setObject:token forKey:@"access_token"]; 211 | [param setObject:wbid forKey:@"id"]; 212 | [param setObject:text forKey:@"comment"]; 213 | if (cid) { 214 | [param setObject:cid forKey:@"cid"]; 215 | } 216 | NSURLRequest *req=[self.client requestWithMethod:@"POST" path:url parameters:param]; 217 | 218 | AVJSONRequestOperation *opt=[AVJSONRequestOperation JSONRequestOperationWithRequest:req success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 219 | callback(JSON,nil); 220 | 221 | } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 222 | callback(JSON,error); 223 | }]; 224 | 225 | [self.client enqueueHTTPRequestOperation:opt]; 226 | }else{ 227 | callback(nil,[NSError errorWithDomain:@"vz" code:1 userInfo:nil]); 228 | } 229 | 230 | } 231 | 232 | -(void)uploadImage:(UIImage*)image callback:(AVSNSResultBlock)callback{ 233 | if (![AVOSCloudSNS doesUserExpireOfPlatform:AVOSCloudSNSSinaWeibo]) { 234 | NSDictionary *dict= [AVOSCloudSNS userInfo:AVOSCloudSNSSinaWeibo]; 235 | NSString *token=[dict objectForKey:@"access_token"]; 236 | 237 | NSString *url=[NSString stringWithFormat:@"https://api.weibo.com/2/statuses/upload_pic.json"]; 238 | 239 | NSMutableDictionary *param=[NSMutableDictionary dictionary]; 240 | [param setObject:token forKey:@"access_token"]; 241 | [param setObject:UIImageJPEGRepresentation(image, 0.8) forKey:@"pic"]; 242 | 243 | NSURLRequest *req=[self.client requestWithMethod:@"POST" path:url parameters:param]; 244 | 245 | AVJSONRequestOperation *opt=[AVJSONRequestOperation JSONRequestOperationWithRequest:req success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 246 | callback(JSON,nil); 247 | 248 | } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 249 | callback(JSON,error); 250 | }]; 251 | 252 | [self.client enqueueHTTPRequestOperation:opt]; 253 | }else{ 254 | callback(nil,[NSError errorWithDomain:@"vz" code:1 userInfo:nil]); 255 | } 256 | } 257 | 258 | @end 259 | 260 | 261 | 262 | 263 | @implementation VZUser 264 | @dynamic avatar; 265 | + (NSString *)parseClassName { 266 | return @"_User"; 267 | } 268 | 269 | -(NSString*)wbid{ 270 | NSString *uid=self[@"authData"][@"weibo"][@"uid"]; 271 | 272 | return uid; 273 | } 274 | 275 | -(void)findMyFriendOnWeibo:(AVArrayResultBlock)callback{ 276 | NSString *uid=[self wbid]; 277 | 278 | if (uid && ![AVOSCloudSNS doesUserExpireOfPlatform:AVOSCloudSNSSinaWeibo]) { 279 | NSString *token=[[self objectForKey:@"authData"] valueForKeyPath:@"weibo.access_token"]; 280 | 281 | NSString *url=[NSString stringWithFormat:@"https://api.weibo.com/2/friendships/friends/ids.json?uid=%@&access_token=%@",uid,token]; 282 | NSURLRequest *req=[NSURLRequest requestWithURL:[NSURL URLWithString:url]]; 283 | 284 | AVJSONRequestOperation *opt=[AVJSONRequestOperation JSONRequestOperationWithRequest:req success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 285 | NSArray *arr= JSON[@"ids"]; 286 | if (arr) { 287 | AVQuery *q=[VZUser query]; 288 | [q whereKey:@"authData.weibo.uid" containedIn:arr]; 289 | 290 | [q findObjectsInBackgroundWithBlock:callback]; 291 | }else{ 292 | callback(Nil,Nil); 293 | } 294 | 295 | } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 296 | callback(Nil,error); 297 | }]; 298 | 299 | [model.client enqueueHTTPRequestOperation:opt]; 300 | }else{ 301 | callback(Nil,[NSError errorWithDomain:@"vz" code:1 userInfo:nil]); 302 | } 303 | } 304 | 305 | -(void)watch:(BOOL)flat post:(VZPost*)post callback:(AVBooleanResultBlock)callback{ 306 | if (flat) { 307 | [post.watchUsers addObject:post]; 308 | }else{ 309 | [post.watchUsers removeObject:self]; 310 | } 311 | 312 | [post saveInBackgroundWithBlock:callback]; 313 | } 314 | 315 | @end -------------------------------------------------------------------------------- /VZ/VZMenuC.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZMenuC.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-20. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZM.h" 10 | #import 11 | @interface VZMenuC :UITableViewController 12 | -(void)onLogin:(id)user; 13 | @end 14 | -------------------------------------------------------------------------------- /VZ/VZMenuC.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZMenuC.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-20. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZMenuC.h" 10 | #import 11 | #import 12 | #import "VZNavView.h" 13 | #import 14 | #import 15 | #import 16 | #import "VZNearC.h" 17 | 18 | #import "VZStatusListC.h" 19 | 20 | CATransform3D CATransform3DMakePerspective(CGPoint center, float disZ) 21 | { 22 | CATransform3D transToCenter = CATransform3DMakeTranslation(-center.x, -center.y, 0); 23 | CATransform3D transBack = CATransform3DMakeTranslation(center.x, center.y, 0); 24 | CATransform3D scale = CATransform3DIdentity; 25 | scale.m34 = -1.0f/disZ; 26 | return CATransform3DConcat(CATransform3DConcat(transToCenter, scale), transBack); 27 | } 28 | CATransform3D CATransform3DPerspect(CATransform3D t, CGPoint center, float disZ) 29 | { 30 | return CATransform3DConcat(t, CATransform3DMakePerspective(center, disZ)); 31 | } 32 | 33 | 34 | @interface VZMenuC () 35 | @property (weak, nonatomic) IBOutlet UIImageView *avatar; 36 | @property (weak, nonatomic) IBOutlet UILabel *userNameLb; 37 | @property (nonatomic) UITapGestureRecognizer *loginTap; 38 | @end 39 | 40 | @implementation VZMenuC 41 | 42 | -(UIStatusBarStyle)preferredStatusBarStyle{ 43 | return UIStatusBarStyleLightContent; 44 | } 45 | 46 | -(void)onLogin:(VZUser*)user{ 47 | [self.avatar setImageWithURL:[NSURL URLWithString:[user objectForKey:@"avatar"]] 48 | placeholderImage:[UIImage imageNamed:@"head"]]; 49 | } 50 | 51 | -(void)onLogout{ 52 | [model logout]; 53 | 54 | self.avatar.image=[UIImage imageNamed:@"head"]; 55 | } 56 | 57 | -(void)login{ 58 | if ([VZUser currentUser]==nil) { 59 | [model login:^(id object, NSError *error) { 60 | if (error) { 61 | NSLog(@"login error %@",[error description]); 62 | }else if(object){ 63 | [self onLogin:object]; 64 | } 65 | }]; 66 | }else{ 67 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"注销" andMessage:@"确定要注销吗?"]; 68 | 69 | [alertView addButtonWithTitle:@"确定" 70 | type:SIAlertViewButtonTypeDestructive 71 | handler:^(SIAlertView *alert) { 72 | [self onLogout]; 73 | }]; 74 | 75 | [alertView addButtonWithTitle:@"取消" 76 | type:SIAlertViewButtonTypeCancel 77 | handler:^(SIAlertView *alert) { 78 | 79 | }]; 80 | 81 | alertView.transitionStyle = SIAlertViewTransitionStyleBounce; 82 | 83 | [alertView show]; 84 | 85 | } 86 | 87 | } 88 | 89 | - (void)dealloc 90 | { 91 | NSLog(@"menu release?"); 92 | } 93 | 94 | -(void)viewWillAppear:(BOOL)animated{ 95 | [super viewWillAppear:animated]; 96 | [AVAnalytics beginLogPageView:@"左菜单"]; 97 | } 98 | 99 | -(void)viewWillDisappear:(BOOL)animated{ 100 | [super viewWillDisappear:animated]; 101 | [AVAnalytics endLogPageView:@"左菜单"]; 102 | } 103 | 104 | - (void)viewDidLoad 105 | { 106 | [super viewDidLoad]; 107 | 108 | self.tableView.tableHeaderView.frame=CGRectMake(0, 0, 10, 0); 109 | 110 | //self.loginTap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(login)]; 111 | //[self.avatar addGestureRecognizer:self.loginTap]; 112 | 113 | [self onLogin:[VZUser currentUser]]; 114 | 115 | } 116 | 117 | //-(void)viewWillAppear:(BOOL)animated{ 118 | // [self.tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)] withRowAnimation:UITableViewRowAnimationRight]; 119 | //} 120 | 121 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 122 | UINavigationController *nav=(id)self.mm_drawerController.centerViewController; 123 | 124 | if (indexPath.section==1) { 125 | [nav setViewControllers:@[[self.storyboard instantiateViewControllerWithIdentifier:@"SettingC"]] animated:NO]; 126 | }else if(indexPath.section==0){ 127 | switch (indexPath.row) { 128 | case 0: 129 | [self login]; 130 | return; 131 | break; 132 | 133 | case 1: 134 | { 135 | UIViewController *vc= [self.storyboard instantiateViewControllerWithIdentifier:@"PostListC"]; 136 | [nav setViewControllers:@[vc] animated:NO]; 137 | } 138 | break; 139 | 140 | case 2: 141 | { 142 | VZNearC *vc= [self.storyboard instantiateViewControllerWithIdentifier:@"NearC"]; 143 | [nav setViewControllers:@[vc] animated:NO]; 144 | break; 145 | } 146 | 147 | case 3: 148 | { 149 | VZStatusListC *vc=[[VZStatusListC alloc] initWithStyle:UITableViewStylePlain]; 150 | [nav setViewControllers:@[vc] animated:NO]; 151 | } 152 | default: 153 | break; 154 | } 155 | } 156 | [self.mm_drawerController closeDrawerAnimated:YES completion:nil]; 157 | } 158 | 159 | 160 | @end 161 | -------------------------------------------------------------------------------- /VZ/VZNavC.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZNavC.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-30. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface VZNavC : UINavigationController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /VZ/VZNavC.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZNavC.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-30. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZNavC.h" 10 | #import 11 | 12 | @interface VZNavC () 13 | @property(nonatomic,strong)UIBarButtonItem *menuItem; 14 | @end 15 | 16 | @implementation VZNavC 17 | 18 | - (void)viewDidLoad 19 | { 20 | 21 | UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom]; 22 | btn.frame=CGRectMake(0, 0, 44, 44); 23 | [btn setImage:[UIImage imageNamed:@"Dots"] forState:UIControlStateNormal]; 24 | 25 | [btn setImageEdgeInsets:UIEdgeInsetsMake(0, -27, 0, 0)]; 26 | 27 | [btn addTarget:self action:@selector(menu:) forControlEvents:UIControlEventTouchUpInside]; 28 | 29 | //UIBarButtonItem *btn=[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Dots"] style:UIBarButtonItemStylePlain target:self action:@selector(menu:)]; 30 | UIBarButtonItem *left=[[UIBarButtonItem alloc] initWithCustomView:btn]; 31 | 32 | self.menuItem=left; 33 | 34 | UIViewController *vc= self.viewControllers[0]; 35 | vc.navigationItem.leftBarButtonItem=self.menuItem; 36 | } 37 | 38 | -(void)menu:(id)sender{ 39 | [self.mm_drawerController toggleDrawerSide:MMDrawerSideLeft animated:YES completion:nil]; 40 | } 41 | -(void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated{ 42 | [super setViewControllers:viewControllers animated:animated]; 43 | UIViewController *vc= viewControllers[0]; 44 | vc.navigationItem.leftBarButtonItem=self.menuItem; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /VZ/VZNavView.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZNavView.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-16. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "VZProgressView.h" 11 | @interface VZNavView : UIView 12 | @property (nonatomic,retain) VZProgressView *refreshView; 13 | @property(nonatomic,retain)UIButton *arrowBtn; 14 | 15 | //+(VZNavView*)shared; 16 | +(float)height; 17 | 18 | -(void)arrowDown; 19 | -(void)arrowLeft; 20 | -(void)showClose:(BOOL)flag; 21 | @end 22 | 23 | 24 | #define REFRESH_TRIGGER 24 25 | #define REFRESH_HEIGHT 80 26 | -------------------------------------------------------------------------------- /VZ/VZNavView.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZNavView.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-16. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | #import "VZNavView.h" 9 | 10 | @interface VZNavView(){ 11 | UIView *contentView; 12 | 13 | } 14 | 15 | @property(nonatomic,retain)UIButton *closeBtn; 16 | @end 17 | 18 | @implementation VZNavView 19 | 20 | +(float)height{ 21 | return 64; 22 | } 23 | 24 | +(VZNavView*)shared{ 25 | static VZNavView *_nav_=Nil; 26 | if (_nav_==Nil) { 27 | _nav_=[VZNavView new]; 28 | } 29 | 30 | return _nav_; 31 | } 32 | - (id)init 33 | { 34 | CGRect frame=CGRectMake(0, 0, 320, [VZNavView height]); 35 | self = [super initWithFrame:frame]; 36 | if (self) { 37 | self.backgroundColor=[UIColor colorWithWhite:0 alpha:0.4]; 38 | 39 | contentView=[[UIView alloc] initWithFrame:CGRectMake(0, [VZNavView height]==64?20:0, frame.size.width, 44)]; 40 | 41 | self.refreshView=[[VZProgressView alloc] initWithWidth:44]; 42 | self.refreshView.progress=1.0; 43 | [contentView addSubview:self.refreshView]; 44 | 45 | 46 | UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom]; 47 | btn.frame=CGRectMake(10, 0, 44, 44); 48 | [btn setImage:[UIImage imageNamed:@"arrow"] forState:UIControlStateNormal]; 49 | 50 | [contentView addSubview:btn]; 51 | self.arrowBtn=btn; 52 | 53 | 54 | 55 | btn=[UIButton buttonWithType:UIButtonTypeCustom]; 56 | btn.frame=CGRectMake(10, 0, 44, 44); 57 | [btn setImage:[UIImage imageNamed:@"close"] forState:UIControlStateNormal]; 58 | [btn addTarget:self action:@selector(onClose:) forControlEvents:UIControlEventTouchUpInside]; 59 | [contentView addSubview:btn]; 60 | self.closeBtn=btn; 61 | self.closeBtn.alpha=0; 62 | 63 | [self addSubview:contentView]; 64 | } 65 | return self; 66 | } 67 | 68 | -(void)arrowDown{ 69 | [UIView animateWithDuration:0.2 animations:^{ 70 | [self.arrowBtn setTransform:CGAffineTransformMakeRotation(-M_PI /2)]; 71 | }]; 72 | } 73 | 74 | -(void)arrowLeft{ 75 | [UIView animateWithDuration:0.2 animations:^{ 76 | [self.arrowBtn setTransform:CGAffineTransformMakeRotation(M_PI /2)]; 77 | }]; 78 | } 79 | 80 | -(void)showClose:(BOOL)flag{ 81 | static BOOL isCloseShow; 82 | if (isCloseShow==flag) { 83 | return; 84 | } 85 | 86 | isCloseShow=flag; 87 | if (flag) { 88 | self.closeBtn.alpha=0; 89 | self.closeBtn.center=CGPointMake(82, 22); 90 | 91 | [UIView animateWithDuration:0.2 animations:^{ 92 | self.closeBtn.alpha=1; 93 | self.closeBtn.center=CGPointMake(22, 22); 94 | 95 | self.arrowBtn.alpha=0; 96 | self.arrowBtn.center=CGPointMake(-22, 22); 97 | }]; 98 | 99 | }else{ 100 | [UIView animateWithDuration:0.2 animations:^{ 101 | self.arrowBtn.alpha=1; 102 | self.arrowBtn.center=CGPointMake(32, 22); 103 | 104 | self.closeBtn.alpha=0; 105 | self.closeBtn.center=CGPointMake(82, 22); 106 | }]; 107 | } 108 | } 109 | 110 | -(void)onClose:(UIButton*)btn{ 111 | 112 | [self showClose:NO]; 113 | } 114 | 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /VZ/VZNearC.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZNearC.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-2. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "VZM.h" 13 | 14 | @interface VZNearC : UIViewController 15 | @property (weak, nonatomic) IBOutlet MKMapView *mapView; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /VZ/VZNearC.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZNearC.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-2. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZNearC.h" 10 | #import 11 | #import 12 | #import "VZProgressView.h" 13 | #import "VZPostViewC.h" 14 | 15 | @interface VZNearC (){ 16 | BOOL gotUserLocation; 17 | BOOL loading; 18 | } 19 | 20 | @property (nonatomic,retain) VZProgressView *refreshView; 21 | @property (nonatomic,assign) CLLocationCoordinate2D lastCoor; 22 | @end 23 | 24 | @implementation VZNearC 25 | 26 | -(void)viewWillAppear:(BOOL)animated{ 27 | [super viewWillAppear:animated]; 28 | [AVAnalytics beginLogPageView:@"地图页面"]; 29 | } 30 | 31 | -(void)viewWillDisappear:(BOOL)animated{ 32 | [super viewWillDisappear:animated]; 33 | [AVAnalytics endLogPageView:@"地图页面"]; 34 | } 35 | 36 | - (void)viewDidLoad 37 | { 38 | [super viewDidLoad]; 39 | self.mapView.userTrackingMode=MKUserTrackingModeNone; 40 | 41 | self.refreshView=[[VZProgressView alloc] initWithWidth:44]; 42 | [self.refreshView setProgress:1 animated:NO]; 43 | self.refreshView.infinite=YES; 44 | self.navigationItem.titleView=self.refreshView; 45 | } 46 | 47 | -(void)reloadPosts{ 48 | if (loading) { 49 | return; 50 | } 51 | loading=YES; 52 | if (!self.refreshView.infinite) { 53 | self.refreshView.infinite=YES; 54 | } 55 | 56 | MKCoordinateRegion region= self.mapView.region; 57 | 58 | AVQuery *q= [VZPost query]; 59 | [q whereKey:@"type" containedIn:@[@0,@2]]; 60 | [q whereKeyExists:@"pics"]; 61 | [q setLimit:60]; 62 | 63 | float kilo=region.span.latitudeDelta*111.0*0.5; 64 | 65 | [q whereKey:@"geo" nearGeoPoint:[AVGeoPoint geoPointWithLatitude:region.center.latitude longitude:region.center.longitude] withinKilometers:kilo]; 66 | 67 | __weak typeof(self) ws=self; 68 | 69 | [q findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { 70 | if (error) { 71 | 72 | }else{ 73 | 74 | NSMutableArray *arr=[NSMutableArray array]; 75 | if (objects.count) { 76 | for (VZPost *post in objects) { 77 | NSUInteger index = [self.mapView.annotations indexOfObjectPassingTest:^BOOL(id otherAnnotation, NSUInteger idx, BOOL *stop) { 78 | return [post coordinate].latitude==[otherAnnotation coordinate].latitude && [post coordinate].longitude==[otherAnnotation coordinate].longitude ; 79 | }]; 80 | if (index == NSNotFound) 81 | { 82 | [arr addObject:post]; 83 | } 84 | } 85 | 86 | 87 | } 88 | if (arr.count>0) { 89 | [ws.mapView addAnnotations:arr]; 90 | } 91 | 92 | } 93 | ws.refreshView.infinite=NO; 94 | [ws.refreshView setProgress:1 animated:NO]; 95 | loading=NO; 96 | }]; 97 | } 98 | 99 | 100 | -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation 101 | { 102 | MKAnnotationView * result = nil; 103 | 104 | NSString * pinReusableIdentifier = @"PostCell"; 105 | MKPinAnnotationView * annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:pinReusableIdentifier]; 106 | if(annotationView == nil) 107 | { 108 | annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinReusableIdentifier]; 109 | 110 | [annotationView setCanShowCallout:YES]; 111 | 112 | annotationView.rightCalloutAccessoryView=[UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 113 | 114 | annotationView.opaque = NO; 115 | annotationView.animatesDrop = YES; 116 | 117 | } 118 | 119 | 120 | 121 | 122 | VZPost *post=(id)annotation; 123 | if ([post isKindOfClass:[VZPost class]]) { 124 | 125 | int type=[[post objectForKey:@"type"] intValue]; 126 | if (type==0) { 127 | annotationView.pinColor=MKPinAnnotationColorPurple; 128 | annotationView.rightCalloutAccessoryView.tintColor=[UIColor purpleColor]; 129 | }else if (type==1){ 130 | annotationView.pinColor=MKPinAnnotationColorRed; 131 | annotationView.rightCalloutAccessoryView.tintColor=[UIColor redColor]; 132 | }else if (type==2){ 133 | annotationView.pinColor=MKPinAnnotationColorGreen; 134 | annotationView.rightCalloutAccessoryView.tintColor=[UIColor greenColor]; 135 | } 136 | 137 | 138 | NSDictionary *user=[post objectForKey:@"user"]; 139 | NSString *url=user[@"avatar_large"]; 140 | if(url==nil){ 141 | url=user[@"avatar"]; 142 | url=[url stringByReplacingOccurrencesOfString:@"/50/" withString:@"/180/"]; 143 | } 144 | 145 | float h=32; 146 | 147 | UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, h, h)]; 148 | [imageView setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"head"]]; 149 | 150 | imageView.clipsToBounds=YES; 151 | imageView.layer.cornerRadius=h*0.5; 152 | 153 | annotationView.leftCalloutAccessoryView = imageView; 154 | }else{ 155 | return nil; 156 | } 157 | result = annotationView; 158 | return result; 159 | } 160 | 161 | -(void)onGetLocation:(CLLocationCoordinate2D)location exact:(BOOL)exact{ 162 | if (CLLocationCoordinate2DIsValid(self.lastCoor)) { 163 | CLLocationDistance dis=ABS([[[CLLocation alloc] initWithLatitude:location.latitude longitude:location.longitude] 164 | distanceFromLocation: 165 | [[CLLocation alloc] initWithLatitude:self.lastCoor.latitude longitude:self.lastCoor.longitude] 166 | ]); 167 | if (dis<5000) { 168 | return; 169 | } 170 | } 171 | 172 | 173 | self.lastCoor=location; 174 | gotUserLocation=YES; 175 | 176 | float kilo=10; 177 | if (exact==NO) { 178 | kilo=50; 179 | } 180 | 181 | MKCoordinateRegion region=MKCoordinateRegionMakeWithDistance(location, kilo*1000, kilo*1000); 182 | [self.mapView setRegion:region animated:YES]; 183 | 184 | [self reloadPosts]; 185 | } 186 | 187 | -(void)onLocationFail{ 188 | gotUserLocation=YES; 189 | 190 | [self reloadPosts]; 191 | } 192 | 193 | -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{ 194 | if (gotUserLocation) { 195 | return; 196 | } 197 | [self onGetLocation:userLocation.location.coordinate exact:YES]; 198 | } 199 | 200 | -(void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error{ 201 | if (gotUserLocation) { 202 | return; 203 | } 204 | 205 | __weak typeof(self) ws=self; 206 | 207 | AVJSONRequestOperation *opt=[AVJSONRequestOperation 208 | JSONRequestOperationWithRequest:[NSURLRequest requestWithURL: 209 | [NSURL URLWithString:@"http://api.map.baidu.com/location/ip?ak=08fadd5a7e397b10f4599c325ee55b9c&coor=bd09ll"]] 210 | success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 211 | 212 | NSDictionary *point=JSON[@"content"][@"point"]; 213 | if (point) { 214 | [ws onGetLocation:CLLocationCoordinate2DMake([point[@"y"] floatValue], [point[@"x"] floatValue]) 215 | exact:NO]; 216 | }else{ 217 | [ws onLocationFail]; 218 | } 219 | } 220 | failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 221 | [ws onLocationFail]; 222 | }]; 223 | 224 | [model.client enqueueHTTPRequestOperation:opt]; 225 | } 226 | 227 | -(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{ 228 | if (!animated) { 229 | [self reloadPosts]; 230 | } 231 | } 232 | 233 | - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { 234 | VZPost *post=(id)view.annotation; 235 | 236 | if ([post isKindOfClass:[VZPost class]]) { 237 | VZPostViewC *pc=[self.storyboard instantiateViewControllerWithIdentifier:@"PostViewC"]; 238 | pc.post=post; 239 | 240 | [self.navigationController pushViewController:pc animated:YES]; 241 | } 242 | 243 | } 244 | 245 | -(void)didReceiveMemoryWarning{ 246 | [self.mapView removeAnnotations:self.mapView.annotations]; 247 | } 248 | 249 | @end 250 | -------------------------------------------------------------------------------- /VZ/VZPost.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZPost.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-26. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | @interface VZPost : AVObject 13 | 14 | @property(nonatomic,copy) NSString *text; 15 | @property(nonatomic,retain) AVGeoPoint *geo; 16 | @property(nonatomic,retain) AVRelation *watchUsers; 17 | 18 | //@property(nonatomic,retain) NSDictionary *user; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /VZ/VZPost.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZPost.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-26. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZPost.h" 10 | 11 | 12 | @implementation VZPost 13 | @dynamic text,geo; 14 | 15 | + (NSString *)parseClassName { 16 | return @"Post"; 17 | } 18 | 19 | -(CLLocationCoordinate2D)coordinate{ 20 | return CLLocationCoordinate2DMake(self.geo.latitude, self.geo.longitude); 21 | } 22 | 23 | -(NSString*)subtitle{ 24 | return self.text; 25 | } 26 | 27 | -(NSString*)title{ 28 | int i=[[self objectForKey:@"type"] intValue]; 29 | 30 | switch (i) { 31 | case 0: 32 | return @"出售"; 33 | 34 | case 1: 35 | return @"求购"; 36 | 37 | case 2: 38 | return @"交易完成"; 39 | } 40 | 41 | return nil; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /VZ/VZPostActionC.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZPostActionC.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-12-8. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | @class VZPostViewC; 11 | @interface VZPostActionC : UITableViewController 12 | @property(nonatomic,assign) BOOL isAuthor; 13 | @property(weak) VZPostViewC *delegate; 14 | @end 15 | -------------------------------------------------------------------------------- /VZ/VZPostActionC.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZPostActionC.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-12-8. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZPostActionC.h" 10 | #import "VZPostViewC.h" 11 | @interface VZPostActionC () 12 | 13 | @end 14 | 15 | @implementation VZPostActionC 16 | 17 | -(void)viewWillAppear:(BOOL)animated{ 18 | [super viewWillAppear:animated]; 19 | [AVAnalytics beginLogPageView:@"右菜单"]; 20 | } 21 | 22 | -(void)viewWillDisappear:(BOOL)animated{ 23 | [super viewWillDisappear:animated]; 24 | [AVAnalytics endLogPageView:@"右菜单"]; 25 | } 26 | 27 | - (void)viewDidLoad 28 | { 29 | [super viewDidLoad]; 30 | 31 | } 32 | 33 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 34 | switch (indexPath.row) { 35 | case 0: 36 | [self.delegate reportSpam]; 37 | break; 38 | 39 | default: 40 | break; 41 | } 42 | } 43 | 44 | //#pragma mark - Table view data source 45 | // 46 | //- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 47 | //{ 48 | //#warning Potentially incomplete method implementation. 49 | // // Return the number of sections. 50 | // return 0; 51 | //} 52 | // 53 | //- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 54 | //{ 55 | //#warning Incomplete method implementation. 56 | // // Return the number of rows in the section. 57 | // return 0; 58 | //} 59 | // 60 | //- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 61 | //{ 62 | // static NSString *CellIdentifier = @"Cell"; 63 | // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 64 | // 65 | // // Configure the cell... 66 | // 67 | // return cell; 68 | //} 69 | 70 | /* 71 | // Override to support conditional editing of the table view. 72 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 73 | { 74 | // Return NO if you do not want the specified item to be editable. 75 | return YES; 76 | } 77 | */ 78 | 79 | /* 80 | // Override to support editing the table view. 81 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 82 | { 83 | if (editingStyle == UITableViewCellEditingStyleDelete) { 84 | // Delete the row from the data source 85 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 86 | } 87 | else if (editingStyle == UITableViewCellEditingStyleInsert) { 88 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 89 | } 90 | } 91 | */ 92 | 93 | /* 94 | // Override to support rearranging the table view. 95 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 96 | { 97 | } 98 | */ 99 | 100 | /* 101 | // Override to support conditional rearranging of the table view. 102 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 103 | { 104 | // Return NO if you do not want the item to be re-orderable. 105 | return YES; 106 | } 107 | */ 108 | 109 | /* 110 | #pragma mark - Navigation 111 | 112 | // In a story board-based application, you will often want to do a little preparation before navigation 113 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 114 | { 115 | // Get the new view controller using [segue destinationViewController]. 116 | // Pass the selected object to the new view controller. 117 | } 118 | 119 | */ 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /VZ/VZPostCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZPostCell.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-26. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "VZM.h" 12 | 13 | @interface UIImageView(Progress) 14 | 15 | - (void)setProgressImageWithURLRequest:(NSURLRequest *)urlRequest 16 | placeholderImage:(UIImage *)placeholderImage; 17 | 18 | @end 19 | 20 | #import "VZProgressView.h" 21 | 22 | @interface VZPostCell : UITableViewCell 23 | @property (weak, nonatomic) IBOutlet UIImageView *photo; 24 | @property (weak, nonatomic) IBOutlet UIImageView *geoIcon; 25 | @property (weak, nonatomic) IBOutlet UILabel *textLb; 26 | @property (weak, nonatomic) IBOutlet UILabel *priceLb; 27 | @property (weak, nonatomic) IBOutlet UIImageView *userAvatar; 28 | @property (weak, nonatomic) IBOutlet UIPageControl *pageControl; 29 | 30 | @property (weak, nonatomic) IBOutlet UIView *container; 31 | 32 | @property (nonatomic) BOOL canAnimate; 33 | 34 | @property (weak, nonatomic) VZPost *post; 35 | @property (weak, nonatomic) UITableView *table; 36 | 37 | -(void)loadPhoto; 38 | -(void)stopLoadPhoto; 39 | @end 40 | 41 | -------------------------------------------------------------------------------- /VZ/VZPostCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZPostCell.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-26. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZPostCell.h" 10 | #import 11 | 12 | @interface AFImageCache : NSCache 13 | - (UIImage *)cachedImageForRequest:(NSURLRequest *)request; 14 | - (void)cacheImage:(UIImage *)image 15 | forRequest:(NSURLRequest *)request; 16 | @end 17 | 18 | #pragma mark - 19 | 20 | @interface UIImageView () 21 | @property (readwrite, nonatomic, strong, setter = af_setImageRequestOperation:) AVImageRequestOperation *af_imageRequestOperation; 22 | + (AFImageCache *)af_sharedImageCache; 23 | +(NSOperationQueue*)af_sharedImageRequestOperationQueue; 24 | @end 25 | 26 | #define avatarFrame CGRectMake(8,17,50,50) 27 | 28 | 29 | @implementation UIImageView(Progress) 30 | 31 | - (void)setProgressImageWithURLRequest:(NSURLRequest *)urlRequest 32 | placeholderImage:(UIImage *)placeholderImage 33 | 34 | { 35 | [self cancelImageRequestOperation]; 36 | [[self viewWithTag:1000] removeFromSuperview]; 37 | 38 | UIImage *cachedImage = [[[self class] af_sharedImageCache] cachedImageForRequest:urlRequest]; 39 | if (cachedImage) { 40 | self.image = cachedImage; 41 | self.af_imageRequestOperation = nil; 42 | self.image = cachedImage; 43 | } else { 44 | self.image = placeholderImage; 45 | 46 | AVImageRequestOperation *requestOperation = [[AVImageRequestOperation alloc] initWithRequest:urlRequest]; 47 | 48 | requestOperation.queuePriority=NSOperationQueuePriorityLow; 49 | 50 | VZProgressView *pv=[[VZProgressView alloc] initWithWidth:self.frame.size.width/2]; 51 | pv.bgLineColor=[UIColor colorWithWhite:1 alpha:0.4]; 52 | pv.fgLineColor=[UIColor whiteColor]; 53 | pv.tag=1000; 54 | 55 | [requestOperation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) { 56 | float progress=totalBytesRead*1.0/totalBytesExpectedToRead; 57 | pv.progress=progress; 58 | }]; 59 | 60 | [self addSubview:pv]; 61 | 62 | [requestOperation setCompletionBlockWithSuccess:^(AVHTTPRequestOperation *operation, id responseObject) { 63 | if ([[urlRequest URL] isEqual:[[self.af_imageRequestOperation request] URL]]) { 64 | self.image = responseObject; 65 | [pv removeFromSuperview]; 66 | self.af_imageRequestOperation = nil; 67 | } 68 | 69 | [[[self class] af_sharedImageCache] cacheImage:responseObject forRequest:urlRequest]; 70 | } failure:^(AVHTTPRequestOperation *operation, NSError *error) { 71 | [pv removeFromSuperview]; 72 | }]; 73 | 74 | self.af_imageRequestOperation = requestOperation; 75 | 76 | [[[self class] af_sharedImageRequestOperationQueue] addOperation:self.af_imageRequestOperation]; 77 | } 78 | } 79 | @end 80 | 81 | @interface VZPostCell() 82 | 83 | @property(weak,nonatomic) NSMutableDictionary *oldFrame; 84 | 85 | @end 86 | 87 | @implementation VZPostCell 88 | 89 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 90 | { 91 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 92 | if (self) { 93 | 94 | } 95 | return self; 96 | } 97 | 98 | -(void)loadPhoto{ 99 | NSArray *pics=[self.post objectForKey:@"pics"]; 100 | if (pics) { 101 | NSString *url=pics[0]; 102 | url=[url stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"bmiddle"]; 103 | 104 | [self.photo setProgressImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] placeholderImage:[UIImage imageNamed:nil]]; 105 | } 106 | 107 | int c=pics.count; 108 | if (c>1) { 109 | self.pageControl.hidden=NO; 110 | [self.pageControl setNumberOfPages:pics.count]; 111 | 112 | }else{ 113 | self.pageControl.hidden=YES; 114 | } 115 | 116 | } 117 | -(void)stopLoadPhoto{ 118 | [self.photo cancelImageRequestOperation]; 119 | } 120 | 121 | -(void)awakeFromNib{ 122 | // self.textLabel.numberOfLines=3; 123 | // self.textLabel.font=[UIFont systemFontOfSize:14]; 124 | 125 | //self.container.clipsToBounds=YES; 126 | //self.container.layer.cornerRadius=5; 127 | 128 | // self.priceLb.layer.borderColor=[UIColor whiteColor].CGColor; 129 | // self.priceLb.layer.borderWidth=1; 130 | // self.priceLb.backgroundColor=[UIColor colorWithWhite:0 alpha:0.3]; 131 | self.textLb.textColor=[VZTheme textColor]; 132 | 133 | self.priceLb.layer.cornerRadius=4; 134 | 135 | self.userAvatar.clipsToBounds=YES; 136 | 137 | self.userAvatar.layer.borderWidth =1; 138 | 139 | self.userAvatar.layer.borderColor=[UIColor whiteColor].CGColor; 140 | 141 | self.photo.backgroundColor=[UIColor clearColor]; 142 | self.userAvatar.layer.cornerRadius=20; 143 | } 144 | 145 | -(void)prepareForReuse{ 146 | [self reset]; 147 | } 148 | 149 | 150 | -(void)reset{ 151 | if (self.oldFrame) { 152 | self.userAvatar.frame=avatarFrame; 153 | self.userAvatar.layer.cornerRadius=25; 154 | 155 | 156 | self.oldFrame=nil; 157 | } 158 | } 159 | 160 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated 161 | { 162 | [super setSelected:selected animated:animated]; 163 | 164 | } 165 | 166 | @end 167 | -------------------------------------------------------------------------------- /VZ/VZPostListC.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZPostListC.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-19. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "VZM.h" 12 | 13 | #import "VZProgressView.h" 14 | #import "VZPostViewC.h" 15 | 16 | #import 17 | 18 | @interface VZPostListC : UITableViewController 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /VZ/VZPostListC.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZPostListC.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-19. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZPostListC.h" 10 | 11 | #import "VZPost.h" 12 | #import "VZPostCell.h" 13 | #import 14 | #import 15 | #import "VZNavView.h" 16 | #import "VZSearchBar.h" 17 | 18 | 19 | #import 20 | 21 | #define QUERY_LIMIT 30 22 | #define ORDER_BY @"createdAt" 23 | 24 | @interface VZPostListC (){ 25 | BOOL updateRefreshView; 26 | BOOL dragStart; 27 | 28 | BOOL isAddNew; 29 | } 30 | @property (nonatomic,retain) NSMutableArray *posts; 31 | @property (nonatomic,copy) NSString *newid; 32 | @property (nonatomic,copy) NSString *lastid; 33 | @property (nonatomic)UIButton *moreBtn; 34 | 35 | @property (nonatomic,retain) VZProgressView *refreshView; 36 | 37 | @property (nonatomic,strong) NSString *keyword; 38 | 39 | 40 | @end 41 | 42 | @implementation VZPostListC 43 | 44 | -(void)setKeyword:(NSString *)keyword{ 45 | _keyword=keyword; 46 | self.lastid=self.newid=nil; 47 | 48 | self.posts=[NSMutableArray array]; 49 | [self.tableView reloadData]; 50 | 51 | self.moreBtn.hidden=YES; 52 | } 53 | 54 | -(UIStatusBarStyle)preferredStatusBarStyle{ 55 | return UIStatusBarStyleLightContent; 56 | } 57 | 58 | 59 | -(void)onSwipe:(UISwipeGestureRecognizer*)swipe{ 60 | 61 | 62 | if (swipe.direction==UISwipeGestureRecognizerDirectionRight) { 63 | [self.mm_drawerController openDrawerSide:MMDrawerSideLeft animated:YES completion:nil]; 64 | }else { 65 | [self.mm_drawerController closeDrawerAnimated:YES completion:nil]; 66 | } 67 | 68 | 69 | } 70 | 71 | -(void)viewWillAppear:(BOOL)animated{ 72 | [super viewWillAppear:animated]; 73 | [AVAnalytics beginLogPageView:@"产品列表"]; 74 | } 75 | 76 | -(void)viewWillDisappear:(BOOL)animated{ 77 | [super viewWillDisappear:animated]; 78 | [AVAnalytics endLogPageView:@"产品列表"]; 79 | } 80 | 81 | - (void)viewDidLoad 82 | { 83 | [super viewDidLoad]; 84 | 85 | if ([self respondsToSelector:@selector(automaticallyAdjustsScrollViewInsets)]) { 86 | self.automaticallyAdjustsScrollViewInsets=NO; 87 | } 88 | 89 | self.title=@" "; 90 | self.newid=[[NSUserDefaults standardUserDefaults] objectForKey:@"CacheCourse"]; 91 | 92 | UISwipeGestureRecognizer *swipe=[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipe:)]; 93 | 94 | swipe.direction=UISwipeGestureRecognizerDirectionRight; 95 | 96 | [self.view addGestureRecognizer:swipe]; 97 | 98 | swipe=[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipe:)]; 99 | 100 | swipe.direction=UISwipeGestureRecognizerDirectionLeft; 101 | 102 | [self.view addGestureRecognizer:swipe]; 103 | // 104 | 105 | self.tableView.backgroundColor=[UIColor clearColor]; 106 | self.tableView.backgroundView=[[UIImageView alloc] initWithImage:[VZTheme bgImage]]; 107 | self.navigationItem.titleView=self.refreshView=[VZProgressView new]; 108 | 109 | self.posts=[NSMutableArray array]; 110 | 111 | UIView *btmV=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 60)]; 112 | 113 | UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom]; 114 | btn.layer.borderWidth=1; 115 | btn.layer.borderColor=[UIColor colorWithWhite:1 alpha:0.8].CGColor; 116 | btn.clipsToBounds=YES; 117 | btn.layer.cornerRadius=4; 118 | btn.frame=CGRectMake(20, 10, 280, 40); 119 | btn.titleLabel.font=[UIFont systemFontOfSize:14]; 120 | 121 | [btn setTitle:@"更 多" forState:UIControlStateNormal]; 122 | [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 123 | [btn setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted]; 124 | [btn addTarget:self action:@selector(loadMore:) forControlEvents:UIControlEventTouchUpInside]; 125 | btn.hidden=YES; 126 | self.moreBtn=btn; 127 | 128 | [btmV addSubview:btn]; 129 | self.tableView.tableFooterView=btmV; 130 | 131 | if (is7orLater()) { 132 | [self.tableView setContentInset:UIEdgeInsetsMake([VZNavView height], 0, 0, 0)]; 133 | } 134 | 135 | UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTitleTap:)]; 136 | [self.navigationItem.titleView addGestureRecognizer:tap]; 137 | 138 | [self resetSearchBtn]; 139 | 140 | 141 | [self loadNew]; 142 | 143 | } 144 | 145 | -(void)resetSearchBtn{ 146 | UIButton *searchBtn=[UIButton buttonWithType:UIButtonTypeCustom]; 147 | searchBtn.frame=CGRectMake(0, 0, 44, 44); 148 | [searchBtn setImage:[UIImage imageNamed:@"search"] forState:UIControlStateNormal]; 149 | [searchBtn setImageEdgeInsets:UIEdgeInsetsMake(0, 20, 0, 0)]; 150 | [searchBtn addTarget:self action:@selector(onSearchBtn:) forControlEvents:UIControlEventTouchUpInside]; 151 | self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc] initWithCustomView:searchBtn]; 152 | 153 | 154 | } 155 | -(void)onSearchBtn:(UIButton*)btn{ 156 | VZSearchBar *tf=[[VZSearchBar alloc] initWithFrame:CGRectMake(0, 0, 100, 28)]; 157 | tf.delegate=self; 158 | self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc] initWithCustomView:tf]; 159 | 160 | [tf becomeFirstResponder]; 161 | } 162 | 163 | -(BOOL)textFieldShouldReturn:(UITextField *)textField{ 164 | [textField resignFirstResponder]; 165 | 166 | NSString *s=textField.text; 167 | 168 | if ([s isEqualToString:self.keyword]) { 169 | return NO; 170 | } 171 | 172 | if (s.length==0) { 173 | [self resetSearchBtn]; 174 | }else{ 175 | [(VZSearchBar*)textField tiny]; 176 | self.keyword=s; 177 | [self loadNew]; 178 | } 179 | 180 | return NO; 181 | } 182 | 183 | -(void)onSearchBarClose:(VZSearchBar*)sb{ 184 | self.keyword=nil; 185 | [self loadNew]; 186 | [self resetSearchBtn]; 187 | } 188 | 189 | -(void)onTitleTap:(UITapGestureRecognizer*)tap{ 190 | [self.tableView scrollRectToVisible:CGRectMake(0, 0, 10, 1) animated:YES]; 191 | } 192 | 193 | -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ 194 | if ([keyPath isEqualToString:@"showPostsWithPicsOnly"]) { 195 | [self.posts removeAllObjects]; 196 | [self loadNew]; 197 | } 198 | } 199 | 200 | 201 | 202 | -(void)onGetNewPosts:(NSArray*)objects isMore:(BOOL)isMore{ 203 | if (objects.count) { 204 | NSMutableArray *newObjs=[NSMutableArray array]; 205 | NSArray *ids= [self.posts valueForKeyPath:@"objectId"]; 206 | for (AVObject *post in objects) { 207 | NSString *pid=post.objectId; 208 | if (![ids containsObject:pid]) { 209 | [newObjs addObject:post]; 210 | } 211 | } 212 | 213 | objects=[newObjs sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:ORDER_BY ascending:NO]]]; 214 | 215 | 216 | long offset=0; 217 | if (isMore) { 218 | offset=self.posts.count; 219 | }else{ 220 | [[NSUserDefaults standardUserDefaults] setObject:self.newid forKey:@"CacheCourse"]; 221 | self.newid=objects[0][ORDER_BY]; 222 | } 223 | 224 | NSIndexSet *iset=[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(offset, objects.count)]; 225 | 226 | [self.posts insertObjects:objects atIndexes:iset]; 227 | if(objects.count>=QUERY_LIMIT){ 228 | self.lastid=[[self.posts lastObject][ORDER_BY] copy]; 229 | self.moreBtn.hidden=NO; 230 | }else{ 231 | self.lastid=nil; 232 | self.moreBtn.hidden=YES; 233 | } 234 | 235 | [self.tableView reloadData]; 236 | 237 | } 238 | 239 | } 240 | 241 | 242 | -(AVQuery*)getQuery{ 243 | 244 | AVQuery *q=[VZPost query]; 245 | q.cachePolicy=kAVCachePolicyNetworkElseCache; 246 | [q orderByDescending:ORDER_BY]; 247 | [q setMaxCacheAge:60*60]; 248 | [q setLimit:QUERY_LIMIT]; 249 | [q whereKeyExists:@"pics"]; 250 | [q whereKey:@"type" equalTo:@(0)]; 251 | 252 | if (self.keyword) { 253 | [q whereKey:@"text" containsString:self.keyword]; 254 | } 255 | 256 | return q; 257 | } 258 | 259 | -(void)loadNew{ 260 | [self showRefresh]; 261 | 262 | AVQuery *q=[self getQuery]; 263 | if (self.newid) { 264 | [q whereKey:ORDER_BY greaterThan:self.newid]; 265 | } 266 | 267 | __weak VZPostListC* ws=self; 268 | 269 | [q findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { 270 | if(error){ 271 | 272 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"出错了" andMessage:[error localizedDescription]]; 273 | 274 | [alertView addButtonWithTitle:@"重试" 275 | type:SIAlertViewButtonTypeDefault 276 | handler:^(SIAlertView *alert) { 277 | [ws showRefresh]; 278 | [ws loadNew]; 279 | }]; 280 | 281 | [alertView addButtonWithTitle:@"取消" 282 | type:SIAlertViewButtonTypeCancel 283 | handler:^(SIAlertView *alert) { 284 | [ws.mm_drawerController openDrawerSide:MMDrawerSideLeft animated:YES completion:nil]; 285 | }]; 286 | 287 | alertView.transitionStyle = SIAlertViewTransitionStyleBounce; 288 | 289 | [alertView show]; 290 | }else{ 291 | [ws onGetNewPosts:objects isMore:NO]; 292 | } 293 | 294 | [self hideRefreshView]; 295 | }]; 296 | } 297 | 298 | -(IBAction)loadMore:(id)sender{ 299 | [AVAnalytics event:@"产品列表-加载更多"]; 300 | if (!self.lastid) {return;}; 301 | 302 | AVQuery *q=[self getQuery]; 303 | 304 | [q whereKey:ORDER_BY lessThan:self.lastid]; 305 | 306 | self.lastid=nil; 307 | 308 | __weak VZPostListC* ws=self; 309 | [ws.moreBtn setTitle:@"" forState:UIControlStateNormal]; 310 | 311 | UIActivityIndicatorView *av=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; 312 | av.center=ws.moreBtn.center; 313 | [av startAnimating]; 314 | [ws.moreBtn.superview addSubview:av]; 315 | ws.moreBtn.userInteractionEnabled=NO; 316 | [q findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { 317 | if(error){ 318 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"出错了" andMessage:[error localizedDescription]]; 319 | 320 | [alertView addButtonWithTitle:@"重试" 321 | type:SIAlertViewButtonTypeDefault 322 | handler:^(SIAlertView *alert) { 323 | [ws loadNew]; 324 | }]; 325 | 326 | [alertView addButtonWithTitle:@"取消" 327 | type:SIAlertViewButtonTypeCancel 328 | handler:^(SIAlertView *alert) { 329 | [ws.mm_drawerController openDrawerSide:MMDrawerSideLeft animated:YES completion:nil]; 330 | }]; 331 | 332 | alertView.transitionStyle = SIAlertViewTransitionStyleBounce; 333 | 334 | [alertView show]; 335 | }else{ 336 | [ws onGetNewPosts:objects isMore:YES]; 337 | 338 | [av removeFromSuperview]; 339 | [ws.moreBtn setTitle:@"更 多" forState:UIControlStateNormal]; 340 | } 341 | 342 | ws.moreBtn.userInteractionEnabled=YES; 343 | }]; 344 | } 345 | 346 | 347 | -(void)hideRefreshView{ 348 | 349 | [UIView animateWithDuration:0.2 animations:^{ 350 | if (is7orLater()) { 351 | [self.tableView setContentInset:UIEdgeInsetsMake([VZNavView height], 0, 0, 0)]; 352 | }else{ 353 | [self.tableView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)]; 354 | } 355 | } completion:^(BOOL finished) { 356 | self.refreshView.infinite=NO; 357 | self.refreshView.progress=1; 358 | updateRefreshView=NO; 359 | }]; 360 | 361 | } 362 | 363 | -(void)showRefresh{ 364 | if (updateRefreshView) { 365 | return; 366 | } 367 | 368 | updateRefreshView=YES; 369 | [UIView animateWithDuration:0.2 animations:^{ 370 | [self.tableView setContentInset:UIEdgeInsetsMake([VZNavView height]+REFRESH_TRIGGER, 0, 0, 0)]; 371 | }]; 372 | 373 | self.refreshView.infinite=YES; 374 | } 375 | 376 | -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ 377 | dragStart=YES; 378 | } 379 | 380 | -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ 381 | float y=scrollView.contentOffset.y; 382 | 383 | if (!updateRefreshView && y<=-REFRESH_TRIGGER-REFRESH_HEIGHT) { 384 | [self.tableView setContentInset:UIEdgeInsetsMake(-y, 0, 0, 0)]; 385 | 386 | [self showRefresh]; 387 | [self loadNew]; 388 | 389 | dragStart=NO; 390 | } 391 | } 392 | 393 | -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ 394 | float y=scrollView.contentOffset.y; 395 | 396 | if (dragStart && !updateRefreshView && y<0) { 397 | [self.refreshView setProgress:(1.0-(-y-REFRESH_HEIGHT)*1.0f/REFRESH_TRIGGER) animated:NO]; 398 | } 399 | } 400 | 401 | #pragma mark - Table view data source 402 | 403 | 404 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 405 | { 406 | return 1; 407 | } 408 | 409 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 410 | { 411 | return self.posts.count; 412 | } 413 | 414 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 415 | { 416 | static NSString *CellIdentifier = @"PostCell0"; 417 | VZPostCell *cell = (id)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 418 | 419 | cell.table=tableView; 420 | 421 | 422 | VZPost *post=self.posts[indexPath.row]; 423 | cell.post=post; 424 | cell.textLb.text= post.text; 425 | 426 | 427 | NSDictionary *user=[post objectForKey:@"user"]; 428 | NSString *url=user[@"avatar"]; 429 | 430 | if (url) { 431 | url=[url stringByReplacingOccurrencesOfString:@"/50/" withString:@"/180/"]; 432 | } 433 | 434 | [cell.userAvatar setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"head"]]; 435 | 436 | 437 | AVGeoPoint *geo=[post objectForKey:@"geo"]; 438 | 439 | if (geo) { 440 | cell.geoIcon.hidden=NO; 441 | }else{ 442 | cell.geoIcon.hidden=YES; 443 | } 444 | 445 | NSString *price=[post objectForKey:@"price"]; 446 | if (price) { 447 | cell.priceLb.hidden=NO; 448 | cell.priceLb.text=[NSString stringWithFormat:@"¥ %@",price]; 449 | }else { 450 | cell.priceLb.hidden=YES; 451 | } 452 | 453 | return cell; 454 | } 455 | 456 | 457 | -(void)tableView:(UITableView *)tableView willDisplayCell:(VZPostCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{ 458 | 459 | if (cell.canAnimate) { 460 | CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 461 | 462 | scaleAnimation.fromValue = [NSNumber numberWithFloat:0.8]; 463 | scaleAnimation.toValue = [NSNumber numberWithFloat:1.0]; 464 | scaleAnimation.duration = .5f; 465 | 466 | scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 467 | 468 | [cell.layer addAnimation:scaleAnimation forKey:@"scale"]; 469 | 470 | cell.canAnimate=NO; 471 | } 472 | 473 | [cell loadPhoto]; 474 | } 475 | 476 | -(void)tableView:(UITableView *)tableView didEndDisplayingCell:(VZPostCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{ 477 | cell.canAnimate=YES; 478 | [cell stopLoadPhoto]; 479 | } 480 | 481 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 482 | VZPost *post=self.posts[indexPath.row]; 483 | VZPostViewC *pc=[self.storyboard instantiateViewControllerWithIdentifier:@"PostViewC"]; 484 | pc.post=post; 485 | 486 | // self.mm_drawerController.rightDrawerViewController=pc; 487 | // 488 | // [self.mm_drawerController openDrawerSide:MMDrawerSideRight animated:YES completion:nil]; 489 | 490 | [self.navigationController pushViewController:pc animated:YES]; 491 | } 492 | @end 493 | -------------------------------------------------------------------------------- /VZ/VZPostViewC.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZPostViewC.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-1. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "VZM.h" 11 | 12 | #import 13 | 14 | @interface VZPostViewC : UITableViewController 15 | @property(nonatomic,retain) VZPost *post; 16 | 17 | -(void)reportSpam; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /VZ/VZPostViewC.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZPostViewC.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-1. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZPostViewC.h" 10 | #import 11 | #import 12 | 13 | #import "VZCommentCell.h" 14 | 15 | #import "VZNavView.h" 16 | 17 | #import "VZStacView.h" 18 | 19 | #import "VZMenuC.h" 20 | 21 | #import "VZPostActionC.h" 22 | 23 | 24 | #define gap 5 25 | 26 | @interface VZPostViewC (){ 27 | BOOL isAuthor; 28 | } 29 | @property (nonatomic,retain) VZProgressView *refreshView; 30 | @property (nonatomic,retain) NSArray *comments; 31 | @property (nonatomic,retain) VZStacView *stac; 32 | 33 | @property (nonatomic,retain) UIView *bottomView; 34 | @property (nonatomic,retain) UITextField *inputView; 35 | @property (nonatomic,retain) UIImageView *userView; 36 | 37 | @end 38 | 39 | @implementation VZPostViewC 40 | -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { 41 | 42 | return YES; 43 | 44 | } 45 | 46 | -(void)onKeyboardChange:(NSNotification*)noti{ 47 | [self.tableView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)]; 48 | } 49 | -(BOOL)textFieldShouldReturn:(UITextField *)textField{ 50 | 51 | [textField resignFirstResponder]; 52 | [self sendComment]; 53 | return NO; 54 | } 55 | 56 | -(void)stacViewOpenChanged:(VZStacView *)stacView{ 57 | self.tableView.tableHeaderView=stacView; 58 | if (stacView.open==NO) { 59 | [self.tableView scrollRectToVisible:CGRectMake(0, 0, 10, 1) animated:YES]; 60 | } 61 | 62 | NSString *msg=stacView.open?@"照片堆打开":@"照片堆关闭"; 63 | [AVAnalytics event:msg]; 64 | } 65 | 66 | -(void)loadPics{ 67 | NSArray *pics=[self.post objectForKey:@"pics"]; 68 | 69 | if (pics.count>0) { 70 | 71 | float h=240; 72 | 73 | if (self.stac) { 74 | [self.stac removeFromSuperview]; 75 | } 76 | 77 | VZStacView *sv=[[VZStacView alloc] 78 | initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, h)]; 79 | sv.delegate=self; 80 | 81 | __block int loaded=0; 82 | 83 | __weak typeof(self) ws=self; 84 | 85 | for (int i=pics.count-1; i>=0; i--) { 86 | 87 | NSString *url=pics[i]; 88 | url=[url stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"bmiddle"]; 89 | AVImageRequestOperation *opt=[AVImageRequestOperation imageRequestOperationWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] success:^(UIImage *image) { 90 | [sv addImage:image]; 91 | 92 | loaded++; 93 | ws.refreshView.progress=loaded*1.0/pics.count; 94 | }]; 95 | 96 | opt.queuePriority=NSOperationQueuePriorityLow; 97 | 98 | [model.client enqueueHTTPRequestOperation:opt]; 99 | } 100 | 101 | self.stac=sv; 102 | self.tableView.tableHeaderView=sv; 103 | 104 | }else{ 105 | self.tableView.tableHeaderView=nil; 106 | } 107 | 108 | } 109 | 110 | -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ 111 | [self.inputView resignFirstResponder]; 112 | } 113 | -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ 114 | float y=scrollView.contentOffset.y; 115 | 116 | [self.stac scroll:y]; 117 | } 118 | 119 | -(void)onBack{ 120 | [self.navigationController popViewControllerAnimated:YES]; 121 | } 122 | 123 | -(void)viewWillAppear:(BOOL)animated{ 124 | [super viewWillAppear:animated]; 125 | [AVAnalytics beginLogPageView:@"产品详情"]; 126 | } 127 | 128 | -(void)viewWillDisappear:(BOOL)animated{ 129 | [super viewWillDisappear:animated]; 130 | [AVAnalytics endLogPageView:@"产品详情"]; 131 | } 132 | 133 | 134 | - (void)viewDidLoad 135 | { 136 | [super viewDidLoad]; 137 | 138 | if ([self respondsToSelector:@selector(automaticallyAdjustsScrollViewInsets)]) { 139 | self.automaticallyAdjustsScrollViewInsets=NO; 140 | //self.navigationController.interactivePopGestureRecognizer.delegate = (id)self; 141 | //[self.navigationController.interactivePopGestureRecognizer setEnabled:YES]; 142 | } 143 | 144 | UIView *bottomView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 80)]; 145 | //bottomView.backgroundColor=[UIColor colorWithWhite:0 alpha:0.7]; 146 | 147 | UIImageView *userV=[[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 40, 40)]; 148 | userV.layer.cornerRadius=20; 149 | userV.clipsToBounds=YES; 150 | [bottomView addSubview:userV]; 151 | self.userView=userV; 152 | 153 | UIImageView *ivBg=[[UIImageView alloc] initWithFrame:CGRectMake(50, 25, 260, 40)]; 154 | ivBg.image=[[UIImage imageNamed:@"chatBg"] stretchableImageWithLeftCapWidth:30 topCapHeight:30]; 155 | 156 | [bottomView addSubview:ivBg]; 157 | 158 | UITextField *tf=[[UITextField alloc] initWithFrame:CGRectMake(65, 25, 230, 40)]; 159 | tf.font=[UIFont systemFontOfSize:14]; 160 | tf.textColor=[UIColor darkTextColor]; 161 | tf.returnKeyType=UIReturnKeySend; 162 | tf.keyboardAppearance=UIKeyboardAppearanceAlert; 163 | self.inputView=tf; 164 | NSArray *cms=@[@"能便宜吗?",@"出了吗?",@"小刀一下吧"]; 165 | int rdm=arc4random()%cms.count; 166 | tf.placeholder=cms[rdm]; 167 | 168 | [bottomView addSubview:tf]; 169 | tf.delegate=self; 170 | self.bottomView=bottomView; 171 | 172 | self.navigationItem.titleView=self.refreshView=[VZProgressView new]; 173 | 174 | // UIBarButtonItem *btn=[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"arrow"] style:UIBarButtonItemStylePlain target:self action:@selector(onBack)]; 175 | // 176 | // 177 | // 178 | // self.navigationItem.leftBarButtonItem=btn; 179 | 180 | self.tableView.backgroundView=[[UIImageView alloc] initWithImage:[VZTheme bgImage]]; 181 | 182 | [self loadPics]; 183 | 184 | NSDictionary *comment=@{@"user":self.post[@"user"],@"text":self.post.text}; 185 | self.comments=@[comment]; 186 | [self.tableView reloadData]; 187 | 188 | if ([VZUser currentUser]) { 189 | UIBarButtonItem *btn2=[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Dots"] style:UIBarButtonItemStylePlain target:self action:@selector(menu:)]; 190 | self.navigationItem.rightBarButtonItem=btn2; 191 | 192 | } 193 | 194 | 195 | [self loadComments]; 196 | } 197 | 198 | 199 | -(void)sendComment{ 200 | NSString *s= self.inputView.text; 201 | if (s.length==0) { 202 | s=self.inputView.placeholder; 203 | } 204 | 205 | __weak typeof(self) ws=self; 206 | [model commentToWbid:[self.post objectForKey:@"wbid"] toCommentId:nil withText:s callback:^(NSDictionary *ret, NSError *error) { 207 | if (error) { 208 | [AVAnalytics event:@"评论失败"]; 209 | 210 | NSString *msg=nil; 211 | if(ret){ 212 | msg=ret[@"error"]; 213 | }else{ 214 | msg=error.userInfo[@"NSLocalizedDescription"]; 215 | } 216 | 217 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"评论失败" andMessage:msg]; 218 | 219 | [alertView addButtonWithTitle:@"重试" 220 | type:SIAlertViewButtonTypeDefault 221 | handler:^(SIAlertView *alert) { 222 | [ws sendComment]; 223 | }]; 224 | 225 | [alertView addButtonWithTitle:@"取消" 226 | type:SIAlertViewButtonTypeCancel 227 | handler:^(SIAlertView *alert) { 228 | ws.inputView.text=nil; 229 | }]; 230 | 231 | alertView.transitionStyle = SIAlertViewTransitionStyleBounce; 232 | 233 | [alertView show]; 234 | }else{ 235 | [AVAnalytics event:@"评论成功"]; 236 | ws.inputView.text=nil; 237 | [ws loadComments]; 238 | } 239 | }]; 240 | 241 | } 242 | 243 | -(void)loadComments{ 244 | self.refreshView.infinite=YES; 245 | [self.userView setImageWithURL:[NSURL URLWithString:[[AVOSCloudSNS userInfo:AVOSCloudSNSSinaWeibo] objectForKey:@"avatar"]] 246 | placeholderImage:[UIImage imageNamed:@"head"]]; 247 | 248 | __weak typeof(self) ws=self; 249 | [model getCommentWithWbid:[self.post objectForKey:@"wbid"] callback:^(NSArray *objects, NSError *error) { 250 | 251 | if (error) { 252 | if ([error.domain isEqualToString:@"vz"] && error.code==1) { 253 | UIView *btmV=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 60)]; 254 | 255 | UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom]; 256 | btn.layer.borderWidth=1; 257 | btn.layer.borderColor=[UIColor colorWithWhite:1 alpha:0.8].CGColor; 258 | btn.clipsToBounds=YES; 259 | btn.layer.cornerRadius=4; 260 | btn.frame=CGRectMake(60, 10, 200, 40); 261 | btn.titleLabel.font=[UIFont systemFontOfSize:14]; 262 | 263 | [btn setTitle:@"登录微博 & 查看评论" forState:UIControlStateNormal]; 264 | [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 265 | [btn setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted]; 266 | [btn addTarget:ws action:@selector(login) forControlEvents:UIControlEventTouchUpInside]; 267 | [btmV addSubview:btn]; 268 | ws.tableView.tableFooterView=btmV; 269 | }else{ 270 | ws.tableView.tableFooterView=self.bottomView; 271 | } 272 | }else { 273 | ws.tableView.tableFooterView=self.bottomView; 274 | if (objects.count){ 275 | NSMutableArray *arr=[NSMutableArray arrayWithObject:ws.comments[0]]; 276 | [arr addObjectsFromArray:objects]; 277 | ws.comments=arr; 278 | [ws.tableView reloadData]; 279 | } 280 | } 281 | ws.refreshView.infinite=NO; 282 | ws.refreshView.progress=1; 283 | }]; 284 | } 285 | 286 | -(void)reportSpamWithMessage:(NSString*)msg{ 287 | AVObject *object=[AVObject objectWithClassName:@"SpamReport"]; 288 | [object setObject:msg forKey:@"msg"]; 289 | [object setObject:self.post forKey:@"post"]; 290 | if ([VZUser currentUser]) { 291 | [object setObject:[VZUser currentUser] forKey:@"reporter"]; 292 | } 293 | 294 | [object saveInBackground]; 295 | } 296 | 297 | -(void)reportSpam{ 298 | [self.mm_drawerController closeDrawerAnimated:YES completion:^(BOOL finished) { 299 | self.mm_drawerController.rightDrawerViewController=nil; 300 | }]; 301 | 302 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"报告" andMessage:nil]; 303 | 304 | [alertView addButtonWithTitle:@"虚假内容" 305 | type:SIAlertViewButtonTypeDestructive 306 | handler:^(SIAlertView *alert) { 307 | [self reportSpamWithMessage:@"虚假内容"]; 308 | }]; 309 | 310 | 311 | [alertView addButtonWithTitle:@"这是广告" 312 | type:SIAlertViewButtonTypeDestructive 313 | handler:^(SIAlertView *alert) { 314 | [self reportSpamWithMessage:@"这是广告"]; 315 | }]; 316 | 317 | [alertView addButtonWithTitle:@"内容不符" 318 | type:SIAlertViewButtonTypeDefault 319 | handler:^(SIAlertView *alert) { 320 | [self reportSpamWithMessage:@"内容不符"]; 321 | }]; 322 | 323 | [alertView addButtonWithTitle:@"取消" 324 | type:SIAlertViewButtonTypeCancel 325 | handler:^(SIAlertView *alert) { 326 | 327 | }]; 328 | 329 | alertView.transitionStyle = SIAlertViewTransitionStyleDropDown; 330 | 331 | [alertView show]; 332 | 333 | } 334 | 335 | -(void)menu:(UIBarButtonItem*)btn{ 336 | 337 | if (self.mm_drawerController.openSide==MMDrawerSideRight) { 338 | [self.mm_drawerController closeDrawerAnimated:YES completion:^(BOOL finished) { 339 | self.mm_drawerController.rightDrawerViewController=nil; 340 | }]; 341 | 342 | }else{ 343 | VZPostActionC *ac=[[UIStoryboard storyboardWithName:@"iPhone" bundle:nil] instantiateViewControllerWithIdentifier:@"VZPostActionC"]; 344 | ac.delegate=self; 345 | self.mm_drawerController.rightDrawerViewController=ac; 346 | 347 | [self.mm_drawerController openDrawerSide:MMDrawerSideRight animated:YES completion:^(BOOL finished) { 348 | 349 | }]; 350 | } 351 | } 352 | 353 | -(void)login{ 354 | __weak typeof(self) ws=self; 355 | [model login:^(id object, NSError *error) { 356 | if (error) { 357 | [AVAnalytics event:@"登陆失败" attributes:@{@"page":@"产品详情",@"reason":[error localizedDescription]}]; 358 | NSLog(@"login error %@",[error description]); 359 | }else if(object){ 360 | [AVAnalytics event:@"登陆成功" attributes:@{@"page":@"产品详情"}]; 361 | 362 | [ws loadComments]; 363 | 364 | UIBarButtonItem *btn2=[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Dots"] style:UIBarButtonItemStylePlain target:self action:@selector(menu:)]; 365 | self.navigationItem.rightBarButtonItem=btn2; 366 | 367 | [self.mm_drawerController.leftDrawerViewController performSelector:@selector(onLogin:) withObject:object]; 368 | } 369 | }]; 370 | } 371 | 372 | 373 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 374 | { 375 | return 1; 376 | } 377 | 378 | //-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ 379 | // if (section==0) { 380 | // UIView *toolView=[[UIView alloc] initWithFrame:CGRectMake(0, 5, 320, 40)]; 381 | // 382 | // UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom]; 383 | // btn.layer.borderWidth=1; 384 | // btn.layer.borderColor=[UIColor colorWithWhite:1 alpha:0.8].CGColor; 385 | // btn.clipsToBounds=YES; 386 | // btn.layer.cornerRadius=4; 387 | // btn.frame=CGRectMake(10, 0, 60, 40); 388 | // btn.titleLabel.font=[UIFont systemFontOfSize:14]; 389 | // 390 | // [btn setTitle:@"收藏" forState:UIControlStateNormal]; 391 | // [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 392 | // [btn setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted]; 393 | // 394 | // [toolView addSubview:btn]; 395 | // 396 | // 397 | // return toolView; 398 | // 399 | // } 400 | // 401 | // return nil; 402 | //} 403 | // 404 | //-(float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ 405 | // return 50; 406 | //} 407 | 408 | 409 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 410 | { 411 | return self.comments.count; 412 | } 413 | 414 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 415 | { 416 | 417 | NSDictionary *comment=self.comments[indexPath.row]; 418 | NSString *text= comment[@"text"]; 419 | 420 | CGSize size= [text sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(220, 500)]; 421 | 422 | return MAX(size.height+35, 50); 423 | } 424 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 425 | { 426 | NSDictionary *comment=self.comments[indexPath.row]; 427 | NSDictionary *user=[comment objectForKey:@"user"]; 428 | 429 | NSString *CellIdentifier = @"CommentCell"; 430 | 431 | NSString *idstr=user[@"idstr"]; 432 | if (idstr==nil || 433 | [idstr isEqualToString:self.post[@"user"][@"id"]]) { 434 | CellIdentifier = @"CommentCell2"; 435 | } 436 | 437 | 438 | VZCommentCell *cell = (id)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 439 | 440 | if (cell == nil) { 441 | cell = [[VZCommentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 442 | } 443 | 444 | 445 | 446 | cell.textLb.text= comment[@"text"]; 447 | 448 | 449 | NSString *url=user[@"avatar_large"]; 450 | if(url==nil){ 451 | url=user[@"avatar"]; 452 | url=[url stringByReplacingOccurrencesOfString:@"/50/" withString:@"/180/"]; 453 | } 454 | 455 | [cell.avatarView setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"head"]]; 456 | 457 | 458 | 459 | return cell; 460 | } 461 | 462 | 463 | 464 | @end 465 | -------------------------------------------------------------------------------- /VZ/VZProgressView.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZProgressView.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-31. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface VZProgressView : UIView 12 | @property(nonatomic,assign) BOOL autoCenter; 13 | 14 | @property(nonatomic,retain) UIBezierPath *path; 15 | @property(nonatomic,retain) UIColor *bgLineColor; 16 | @property(nonatomic,retain) UIColor *fgLineColor; 17 | 18 | @property(nonatomic,assign) BOOL infinite; 19 | @property(nonatomic,assign) BOOL dashBgLine; 20 | @property(nonatomic,assign) float progress; 21 | @property(nonatomic,assign) float lineWidth; 22 | 23 | 24 | - (id)initWithWidth:(float)width; 25 | 26 | -(void)setProgress:(float)p animated:(BOOL)animated; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /VZ/VZProgressView.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZProgressView.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-31. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZProgressView.h" 10 | #import 11 | 12 | @interface VZProgressView(){ 13 | 14 | } 15 | @property(nonatomic,retain) CAShapeLayer *shapeLayer; 16 | @property(nonatomic,retain) CAShapeLayer *bgLayer; 17 | 18 | @end 19 | 20 | @implementation VZProgressView 21 | +(instancetype)new{ 22 | VZProgressView *v=[[self alloc] initWithWidth:44]; 23 | v.progress=1; 24 | return v; 25 | } 26 | - (id)initWithWidth:(float)width 27 | { 28 | float height=width*0.5; 29 | CGRect frame=CGRectMake(0, 0, width, height); 30 | self = [super initWithFrame:frame]; 31 | if (self) { 32 | self.backgroundColor=[UIColor clearColor]; 33 | 34 | self.autoCenter=YES; 35 | 36 | self.shapeLayer=[CAShapeLayer layer]; 37 | self.shapeLayer.lineCap=kCALineCapRound; 38 | self.shapeLayer.strokeEnd=0; 39 | self.shapeLayer.fillColor=[UIColor clearColor].CGColor; 40 | 41 | self.bgLayer=[CAShapeLayer layer]; 42 | self.bgLayer.lineCap=kCALineCapRound; 43 | self.bgLayer.fillColor=[UIColor clearColor].CGColor; 44 | 45 | [self.layer addSublayer:self.bgLayer]; 46 | [self.layer addSublayer:self.shapeLayer]; 47 | 48 | self.lineWidth=1; 49 | self.dashBgLine=YES; 50 | self.fgLineColor=[UIColor whiteColor]; 51 | self.bgLineColor=[UIColor lightGrayColor]; 52 | 53 | UIBezierPath* bezierPath = [UIBezierPath bezierPath]; 54 | [bezierPath moveToPoint:CGPointMake(0, 0)]; 55 | [bezierPath addLineToPoint:CGPointMake(width/4, height)]; 56 | [bezierPath addLineToPoint:CGPointMake(width/2, 0)]; 57 | [bezierPath addLineToPoint:CGPointMake(width,0)]; 58 | [bezierPath addLineToPoint:CGPointMake(width/2, height)]; 59 | [bezierPath addLineToPoint:CGPointMake(width, height)]; 60 | self.path=bezierPath; 61 | 62 | } 63 | return self; 64 | } 65 | 66 | - (id)initWithFrame:(CGRect)frame 67 | { 68 | return [self initWithWidth:frame.size.width]; 69 | } 70 | 71 | -(void)willMoveToSuperview:(UIView *)newSuperview{ 72 | if (self.autoCenter) { 73 | CGSize s=newSuperview.bounds.size; 74 | self.center=CGPointMake(s.width/2, s.height/2); 75 | } 76 | } 77 | 78 | -(void)setDashBgLine:(BOOL)dashBgLine{ 79 | if (dashBgLine) { 80 | self.bgLayer.lineDashPattern=@[@(2),@(2),@(2),@(2)]; 81 | }else{ 82 | self.bgLayer.lineDashPattern=nil; 83 | } 84 | } 85 | 86 | -(void)setLineWidth:(float)lineWidth{ 87 | self.shapeLayer.lineWidth=lineWidth; 88 | self.bgLayer.lineWidth=lineWidth; 89 | } 90 | 91 | -(void)setPath:(UIBezierPath *)path{ 92 | self.shapeLayer.path=path.CGPath; 93 | self.bgLayer.path=path.CGPath; 94 | } 95 | 96 | -(void)setFgLineColor:(UIColor *)fgLineColor{ 97 | self.shapeLayer.strokeColor = [fgLineColor CGColor]; 98 | } 99 | 100 | -(void)setBgLineColor:(UIColor *)bgLineColor{ 101 | self.bgLayer.strokeColor = [bgLineColor CGColor]; 102 | } 103 | 104 | -(void)setProgress:(float)progress{ 105 | [self setProgress:progress animated:YES]; 106 | } 107 | 108 | -(void)setProgress:(float)p animated:(BOOL)animated{ 109 | _progress=p; 110 | self.shapeLayer.strokeEnd=p;return; 111 | if (animated) { 112 | [self.shapeLayer removeAllAnimations]; 113 | [CATransaction begin]; 114 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 115 | animation.duration = (p-_progress)*0.25; 116 | animation.fromValue = [NSNumber numberWithFloat:self.shapeLayer.strokeEnd]; 117 | animation.toValue = [NSNumber numberWithFloat:p]; 118 | animation.fillMode = kCAFillModeForwards; 119 | animation.removedOnCompletion=NO; 120 | animation.autoreverses = NO; 121 | [self.shapeLayer addAnimation:animation forKey:@"strokeEnd"]; 122 | [CATransaction commit]; 123 | 124 | }else{ 125 | self.shapeLayer.strokeEnd=p; 126 | } 127 | 128 | } 129 | 130 | -(void)setInfinite:(BOOL)infinite{ 131 | if (infinite) { 132 | [self.shapeLayer removeAllAnimations]; 133 | 134 | float dur=2; 135 | 136 | [CATransaction begin]; 137 | 138 | CAAnimationGroup *group=[CAAnimationGroup animation]; 139 | 140 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 141 | animation.duration =dur; 142 | animation.fromValue = [NSNumber numberWithFloat:0]; 143 | animation.toValue = [NSNumber numberWithFloat:1]; 144 | 145 | 146 | CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"strokeStart"]; 147 | animation2.beginTime=dur; 148 | animation2.duration =dur; 149 | animation2.fromValue = [NSNumber numberWithFloat:0]; 150 | animation2.toValue = [NSNumber numberWithFloat:1]; 151 | 152 | group.duration =dur*2.0; 153 | group.fillMode = kCAFillModeForwards; 154 | group.autoreverses = YES; 155 | group.repeatCount=65530; 156 | group.animations=@[animation,animation2]; 157 | 158 | [self.shapeLayer addAnimation:group forKey:@"stroke"]; 159 | 160 | [CATransaction commit]; 161 | }else{ 162 | [self.shapeLayer removeAllAnimations]; 163 | [self setProgress:_progress animated:NO]; 164 | } 165 | } 166 | 167 | @end 168 | -------------------------------------------------------------------------------- /VZ/VZSearchBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZSearchBar.h 3 | // VZ 4 | // 5 | // Created by Travis on 14-2-13. 6 | // Copyright (c) 2014年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class VZSearchBar; 12 | @protocol VZSearchBar 13 | 14 | -(void)onSearchBarClose:(VZSearchBar*)searchBar; 15 | 16 | @end 17 | 18 | @interface VZSearchBar : UITextField 19 | -(void)tiny; 20 | @end 21 | -------------------------------------------------------------------------------- /VZ/VZSearchBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZSearchBar.m 3 | // VZ 4 | // 5 | // Created by Travis on 14-2-13. 6 | // Copyright (c) 2014年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZSearchBar.h" 10 | 11 | #define SB_LEFT_MG 10 12 | 13 | @interface VZSearchBar () 14 | @property(nonatomic,assign)CGRect origFram; 15 | @property(nonatomic,assign)BOOL addAnimated; 16 | @end 17 | 18 | @implementation VZSearchBar 19 | 20 | - (id)initWithFrame:(CGRect)frame 21 | { 22 | self = [super initWithFrame:frame]; 23 | if (self) { 24 | self.origFram=frame; 25 | self.frame=CGRectMake(frame.origin.x, frame.origin.y, frame.size.height, frame.size.height); 26 | // self.layer.borderWidth=1; 27 | // self.layer.borderColor=[UIColor colorWithWhite:1 alpha:0.7].CGColor; 28 | self.layer.cornerRadius=frame.size.height/2; 29 | 30 | self.backgroundColor=[UIColor colorWithWhite:0.7 alpha:0.6]; 31 | //self.backgroundColor=[UIColor clearColor]; 32 | self.textColor=[UIColor colorWithWhite:1 alpha:0.7]; 33 | self.font=[UIFont systemFontOfSize:14]; 34 | 35 | self.keyboardAppearance=UIKeyboardAppearanceAlert; 36 | self.autocorrectionType=UITextAutocorrectionTypeNo; 37 | self.returnKeyType=UIReturnKeySearch; 38 | } 39 | return self; 40 | } 41 | 42 | -(void)tiny{ 43 | float w=[self.text sizeWithFont:self.font forWidth:self.origFram.size.width lineBreakMode:0].width+SB_LEFT_MG*2+13; 44 | 45 | CGRect f=self.frame; 46 | f.size.width=w; 47 | 48 | UIImageView *cls=[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"searchClose"]]; 49 | cls.frame=CGRectMake(w-20, (f.size.height-16)/2, 16, 16); 50 | [self addSubview:cls]; 51 | 52 | self.frame=f; 53 | self.backgroundColor=[UIColor colorWithWhite:0.7 alpha:0.6]; 54 | self.layer.borderWidth=0; 55 | //self.textColor=[UIColor colorWithRed:0 green:0 blue:0.7 alpha:1]; 56 | 57 | UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap)]; 58 | [self addGestureRecognizer:tap]; 59 | } 60 | 61 | -(void)onTap{ 62 | [self.delegate performSelector:@selector(onSearchBarClose:) withObject:self]; 63 | } 64 | 65 | -(void)willMoveToSuperview:(UIView *)newSuperview{ 66 | if (newSuperview && self.addAnimated==NO) { 67 | self.addAnimated=YES; 68 | [UIView animateWithDuration:0.15 animations:^{ 69 | self.frame=self.origFram; 70 | }]; 71 | } 72 | } 73 | 74 | - (CGRect)textRectForBounds:(CGRect)bounds { 75 | int leftMargin = SB_LEFT_MG; 76 | CGRect inset = CGRectMake(bounds.origin.x + leftMargin, bounds.origin.y, bounds.size.width - leftMargin, bounds.size.height); 77 | return inset; 78 | } 79 | 80 | - (CGRect)editingRectForBounds:(CGRect)bounds { 81 | int leftMargin = SB_LEFT_MG; 82 | CGRect inset = CGRectMake(bounds.origin.x + leftMargin, bounds.origin.y, bounds.size.width - leftMargin, bounds.size.height); 83 | return inset; 84 | } 85 | 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /VZ/VZSettingsC.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZSettingsC.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-19. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface VZSettingsC : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /VZ/VZSettingsC.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZSettingsC.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-19. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZSettingsC.h" 10 | #import "VZM.h" 11 | #import 12 | #import 13 | 14 | #import "VZWebViewC.h" 15 | 16 | @interface VZSettingsC () 17 | @property (weak, nonatomic) IBOutlet UILabel *weiboName; 18 | @property (weak, nonatomic) IBOutlet UITextView *footer; 19 | 20 | @end 21 | 22 | @implementation VZSettingsC 23 | 24 | -(void)viewWillAppear:(BOOL)animated{ 25 | [super viewWillAppear:animated]; 26 | [AVAnalytics beginLogPageView:@"设置页面"]; 27 | } 28 | 29 | -(void)viewWillDisappear:(BOOL)animated{ 30 | [super viewWillDisappear:animated]; 31 | [AVAnalytics endLogPageView:@"设置页面"]; 32 | } 33 | 34 | - (void)viewDidLoad 35 | { 36 | [super viewDidLoad]; 37 | 38 | self.tableView.backgroundView=[[UIImageView alloc] initWithImage:[VZTheme bgImage]]; 39 | 40 | UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openAvos)]; 41 | [self.footer addGestureRecognizer:tap]; 42 | 43 | [self reloadWeibo]; 44 | } 45 | -(void)openAvos{ 46 | VZWebViewC *wc= [[VZWebViewC alloc] init]; 47 | [wc loadURL:@"http://cn.avoscloud.com?src=vzapp"]; 48 | 49 | [self.navigationController pushViewController:wc animated:YES]; 50 | 51 | [AVAnalytics event:@"打开AVOSCloud"]; 52 | } 53 | -(void)reloadWeibo{ 54 | NSString *name= [AVOSCloudSNS userInfo:AVOSCloudSNSSinaWeibo][@"username"]; 55 | self.weiboName.text=name?[@"@" stringByAppendingString:name]:@"未绑定"; 56 | } 57 | 58 | -(void)clearCache{ 59 | 60 | } 61 | 62 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 63 | 64 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 65 | 66 | switch (indexPath.row) { 67 | case 0: 68 | 69 | { 70 | __weak typeof(self) ws=self; 71 | if ([VZUser currentUser]==nil) { 72 | [model login:^(id object, NSError *error) { 73 | if (error) { 74 | NSLog(@"login error %@",[error description]); 75 | }else if(object){ 76 | [ws reloadWeibo]; 77 | } 78 | }]; 79 | }else{ 80 | 81 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"注销" andMessage:@"确定要注销吗?"]; 82 | 83 | [alertView addButtonWithTitle:@"确定" 84 | type:SIAlertViewButtonTypeDestructive 85 | handler:^(SIAlertView *alert) { 86 | [model logout]; 87 | [ws reloadWeibo]; 88 | }]; 89 | 90 | [alertView addButtonWithTitle:@"取消" 91 | type:SIAlertViewButtonTypeCancel 92 | handler:^(SIAlertView *alert) { 93 | 94 | }]; 95 | 96 | alertView.transitionStyle = SIAlertViewTransitionStyleBounce; 97 | 98 | [alertView show]; 99 | 100 | } 101 | } 102 | break; 103 | 104 | case 1: 105 | { 106 | 107 | [self.navigationController 108 | pushViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"FeedbackC"] 109 | animated:YES]; 110 | } 111 | break; 112 | 113 | 114 | case 2: 115 | { 116 | 117 | NSString *url = [NSString stringWithFormat:@"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%@",@"768074220"]; 118 | 119 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]]; 120 | 121 | return; 122 | 123 | __weak typeof(self) ws=self; 124 | 125 | SKStoreProductViewController *storeProductViewController = [[SKStoreProductViewController alloc] init]; 126 | // Configure View Controller 127 | [storeProductViewController setDelegate:(id)self]; 128 | [storeProductViewController loadProductWithParameters:@{SKStoreProductParameterITunesItemIdentifier : @"768074220"} 129 | 130 | completionBlock:^(BOOL result, NSError *error) { 131 | if (error) { 132 | NSLog(@"Error %@ with User Info %@.", error, [error userInfo]); 133 | 134 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"出错了" andMessage:[error localizedDescription]]; 135 | 136 | [alertView addButtonWithTitle:@"确定" 137 | type:SIAlertViewButtonTypeCancel 138 | handler:^(SIAlertView *alert) { 139 | [ws dismissViewControllerAnimated:YES completion:nil]; 140 | }]; 141 | 142 | alertView.transitionStyle = SIAlertViewTransitionStyleDropDown; 143 | 144 | [alertView show]; 145 | 146 | 147 | } 148 | }]; 149 | [self presentViewController:storeProductViewController animated:YES completion:nil]; 150 | } 151 | break; 152 | default: 153 | break; 154 | } 155 | } 156 | 157 | - (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController { 158 | [self dismissViewControllerAnimated:YES completion:nil]; 159 | } 160 | @end 161 | -------------------------------------------------------------------------------- /VZ/VZStacView.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZStacView.h 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-20. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class VZStacView; 12 | @protocol VZStacViewDelegate 13 | 14 | -(void)stacViewOpenChanged:(VZStacView*)stacView; 15 | 16 | @end 17 | 18 | @interface VZStacView : UIView 19 | @property(nonatomic,assign)CGRect initFrame; 20 | @property(nonatomic,assign) BOOL open; 21 | @property(nonatomic,assign) id delegate; 22 | @property(nonatomic,assign) int totalCountToShow; 23 | 24 | -(void)addImage:(UIImage*)img; 25 | 26 | -(void)scroll:(float)y; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /VZ/VZStacView.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZStacView.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-11-20. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZStacView.h" 10 | #import "VZM.h" 11 | 12 | #define WHRate 0.6 13 | #define TRIGGER_DLT 0.4 14 | @interface VZStacView () 15 | { 16 | int count; 17 | float imageH; 18 | 19 | CGRect imgFrame; 20 | float scrollY; 21 | 22 | } 23 | @end 24 | 25 | @implementation VZStacView 26 | 27 | - (id)initWithFrame:(CGRect)frame 28 | { 29 | self = [super initWithFrame:frame]; 30 | if (self) { 31 | self.initFrame=frame; 32 | 33 | float w=frame.size.width-8; 34 | 35 | imageH=w*WHRate; 36 | imgFrame=CGRectMake(4, frame.size.height-imageH, w, imageH); 37 | 38 | UIPinchGestureRecognizer *pg=[[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(close)]; 39 | [self addGestureRecognizer:pg]; 40 | 41 | self.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 42 | 43 | } 44 | return self; 45 | } 46 | 47 | -(void)close{ 48 | [self setOpen:NO]; 49 | } 50 | 51 | -(void)addImage:(UIImage*)img{ 52 | if (self.open) { 53 | return; 54 | } 55 | UIImageView *imgv=[[UIImageView alloc] initWithImage:img]; 56 | imgv.contentMode=UIViewContentModeScaleAspectFill; 57 | imgv.clipsToBounds=YES; 58 | imgv.frame=imgFrame; 59 | 60 | imgv.tag=count; 61 | imgv.alpha=0.2; 62 | count++; 63 | 64 | [UIView beginAnimations:@"add" context:nil]; 65 | [UIView setAnimationDuration:0.2]; 66 | [self insertSubview:imgv atIndex:count]; 67 | [self scroll:0]; 68 | [UIView commitAnimations]; 69 | } 70 | 71 | -(void)scroll:(float)y{ 72 | 73 | if (self.open) { 74 | return; 75 | } 76 | 77 | float dlt=-y/self.initFrame.size.height; 78 | 79 | if (dlt>=TRIGGER_DLT) { 80 | self.open=YES; 81 | return; 82 | } 83 | dlt=MAX(0.02, dlt); 84 | [self layoutWithDelta:dlt]; 85 | } 86 | 87 | 88 | -(void)layoutWithDelta:(float)dlt{ 89 | CGRect f=self.frame; 90 | 91 | float gapH=imageH*dlt/5.0; 92 | 93 | for (UIImageView *imgv in self.subviews) { 94 | float scale=1.0-(count-imgv.tag-1)*(TRIGGER_DLT-dlt)*0.2; 95 | imgv.transform=CGAffineTransformScale(CGAffineTransformIdentity,scale, scale); 96 | 97 | float y=f.size.height-imageH*(1.0-scale*0.5)-(count-imgv.tag)*gapH; 98 | imgv.center=CGPointMake(self.initFrame.size.width/2, y); 99 | imgv.alpha=scale; 100 | 101 | //NSLog(@"Img:%d scale:%.02f y:%.02f",imgv.tag,scale,y); 102 | } 103 | } 104 | 105 | -(void)setOpen:(BOOL)open{ 106 | _open=open; 107 | 108 | [UIView animateWithDuration:0.25 animations:^{ 109 | if (open) { 110 | float h= is7orLater() ?44:5; 111 | 112 | for (UIImageView *imgv in self.subviews) { 113 | CGSize size=imgv.image.size; 114 | 115 | imgv.transform=CGAffineTransformIdentity; 116 | imgv.alpha=1; 117 | 118 | 119 | float r=size.width/imgFrame.size.width; 120 | 121 | 122 | 123 | CGRect f=imgFrame; 124 | f.origin.y=h; 125 | f.size.height=size.height/r; 126 | 127 | imgv.frame=f; 128 | imgv.contentMode=UIViewContentModeScaleToFill; 129 | 130 | h+=f.size.height+4; 131 | } 132 | 133 | CGRect f=self.initFrame; 134 | f.size.height=h; 135 | self.frame=f; 136 | 137 | }else{ 138 | 139 | 140 | for (UIImageView *imgv in self.subviews) { 141 | imgv.transform=CGAffineTransformIdentity; 142 | imgv.frame=imgFrame; 143 | imgv.contentMode=UIViewContentModeScaleAspectFill; 144 | } 145 | [self scroll:0]; 146 | self.frame=self.initFrame; 147 | } 148 | [self.delegate stacViewOpenChanged:self]; 149 | } completion:^(BOOL finished) { 150 | 151 | }]; 152 | 153 | } 154 | 155 | @end 156 | -------------------------------------------------------------------------------- /VZ/VZStatusListC.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZStatusListC.h 3 | // VZ 4 | // 5 | // Created by Travis on 14-1-5. 6 | // Copyright (c) 2014年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface VZStatusListC : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /VZ/VZStatusListC.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZStatusListC.m 3 | // VZ 4 | // 5 | // Created by Travis on 14-1-5. 6 | // Copyright (c) 2014年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZStatusListC.h" 10 | #import "VZM.h" 11 | #import "VZNavView.h" 12 | #import "VZWebViewC.h" 13 | #import 14 | #import "VZPostViewC.h" 15 | @interface VZStatusListC (){ 16 | BOOL dragStart; 17 | BOOL updateRefreshView; 18 | } 19 | @property (nonatomic,strong) NSArray *statuses; 20 | @property (nonatomic,retain) VZProgressView *refreshView; 21 | @end 22 | 23 | @implementation VZStatusListC 24 | 25 | - (id)initWithStyle:(UITableViewStyle)style 26 | { 27 | self = [super initWithStyle:style]; 28 | if (self) { 29 | self.navigationItem.titleView=self.refreshView=[VZProgressView new]; 30 | } 31 | return self; 32 | } 33 | -(void)viewWillAppear:(BOOL)animated{ 34 | [super viewWillAppear:animated]; 35 | [AVAnalytics beginLogPageView:@"消息列表"]; 36 | } 37 | 38 | -(void)viewWillDisappear:(BOOL)animated{ 39 | [super viewWillDisappear:animated]; 40 | [AVAnalytics endLogPageView:@"消息列表"]; 41 | } 42 | - (void)viewDidLoad 43 | { 44 | [super viewDidLoad]; 45 | self.tableView.backgroundColor=[UIColor clearColor]; 46 | self.tableView.backgroundView=[[UIImageView alloc] initWithImage:[VZTheme bgImage]]; 47 | 48 | self.tableView.separatorStyle=UITableViewCellSeparatorStyleNone; 49 | 50 | 51 | 52 | UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTitleTap:)]; 53 | [self.navigationItem.titleView addGestureRecognizer:tap]; 54 | 55 | [self loadNew]; 56 | 57 | 58 | } 59 | -(void)onTitleTap:(UITapGestureRecognizer*)tap{ 60 | [self.tableView scrollRectToVisible:CGRectMake(0, 0, 10, 1) animated:YES]; 61 | } 62 | 63 | -(void)hideRefreshView{ 64 | 65 | [UIView animateWithDuration:0.2 animations:^{ 66 | [self.tableView setContentInset:UIEdgeInsetsMake([VZNavView height], 0, 0, 0)]; 67 | } completion:^(BOOL finished) { 68 | self.refreshView.infinite=NO; 69 | self.refreshView.progress=1; 70 | updateRefreshView=NO; 71 | }]; 72 | 73 | } 74 | 75 | -(void)showRefresh{ 76 | if (updateRefreshView) { 77 | return; 78 | } 79 | 80 | updateRefreshView=YES; 81 | [UIView animateWithDuration:0.2 animations:^{ 82 | [self.tableView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)]; 83 | }]; 84 | 85 | self.refreshView.infinite=YES; 86 | } 87 | 88 | -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ 89 | dragStart=YES; 90 | } 91 | 92 | -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ 93 | float y=scrollView.contentOffset.y; 94 | 95 | if (!updateRefreshView && y<=-REFRESH_TRIGGER-REFRESH_HEIGHT) { 96 | [self.tableView setContentInset:UIEdgeInsetsMake(-y, 0, 0, 0)]; 97 | 98 | [self showRefresh]; 99 | [self loadNew]; 100 | 101 | dragStart=NO; 102 | } 103 | } 104 | 105 | -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ 106 | float y=scrollView.contentOffset.y; 107 | 108 | if (dragStart && !updateRefreshView && y<0) { 109 | [self.refreshView setProgress:(1.0-(-y-REFRESH_HEIGHT)*1.0f/REFRESH_TRIGGER) animated:NO]; 110 | } 111 | } 112 | 113 | 114 | -(void)loadNew{ 115 | __weak typeof(self) ws=self; 116 | [AVStatus getStatusesWithType:kAVStatusTypeTimeline skip:0 limit:100 andCallback:^(NSArray *objects, NSError *error) { 117 | 118 | AVStatus *status=[[AVStatus alloc] init]; 119 | [status setData:@{ 120 | @"text":@"hello link", 121 | @"content":@"http://weibo.com", 122 | }]; 123 | 124 | AVStatus *status3=[[AVStatus alloc] init]; 125 | [status3 setData:@{ 126 | @"text":@"hello store", 127 | @"content":@"http://itunes.apple.com/us/app/iq-test-sale/id297141027?mt=8&uo=6", 128 | }]; 129 | 130 | AVStatus *status2=[[AVStatus alloc] init]; 131 | [status2 setData:@{ 132 | @"text":@"hello post", 133 | @"content":@"post://52d202a3e4b04a44920e736a", 134 | }]; 135 | 136 | objects=@[status,status2,status3]; 137 | ws.statuses=objects; 138 | 139 | dispatch_async(dispatch_get_main_queue(), ^{ 140 | [ws.tableView reloadData]; 141 | [ws hideRefreshView]; 142 | 143 | }); 144 | 145 | 146 | 147 | }]; 148 | } 149 | 150 | #pragma mark - Table view data source 151 | 152 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 153 | { 154 | return 1; 155 | 156 | } 157 | 158 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 159 | { 160 | return self.statuses.count; 161 | } 162 | 163 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 164 | { 165 | static NSString *CellIdentifier = @"StatusCell"; 166 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 167 | 168 | if (cell==nil) { 169 | cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 170 | cell.backgroundColor=[UIColor colorWithWhite:1 alpha:0.3]; 171 | cell.contentView.backgroundColor=[UIColor clearColor]; 172 | cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator; 173 | 174 | cell.imageView.clipsToBounds=YES; 175 | cell.imageView.layer.cornerRadius=20; 176 | } 177 | 178 | AVStatus *status=[self.statuses objectAtIndex:indexPath.row]; 179 | NSDictionary *data=status.data; 180 | 181 | cell.textLabel.text=data[@"text"]; 182 | 183 | id source=status.source; 184 | if (source) { 185 | 186 | }else{ 187 | cell.imageView.image=[UIImage imageNamed:@"head"]; 188 | } 189 | 190 | return cell; 191 | } 192 | 193 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 194 | 195 | AVStatus *status=[self.statuses objectAtIndex:indexPath.row]; 196 | NSDictionary *data=status.data; 197 | NSString *content= data[@"content"]; 198 | 199 | NSArray *cpt=[content componentsSeparatedByString:@"://"]; 200 | 201 | NSString *scheme=cpt[0]; 202 | 203 | self.refreshView.infinite=YES; 204 | self.view.userInteractionEnabled=NO; 205 | __weak typeof(self) ws=self; 206 | 207 | if ([scheme hasPrefix:@"post"]) { 208 | VZPost *post=[VZPost objectWithoutDataWithObjectId:cpt[1]]; 209 | [post fetchIfNeededInBackgroundWithBlock:^(AVObject *object, NSError *error) { 210 | ws.view.userInteractionEnabled=YES; 211 | ws.refreshView.infinite=NO; 212 | 213 | if (object) { 214 | VZPostViewC *vc=[[VZPostViewC alloc] init]; 215 | vc.post=(id)object; 216 | [ws.navigationController pushViewController:vc animated:YES]; 217 | }else{ 218 | NSString *msg=@"无法获取内容"; 219 | if (error) { 220 | msg=[error localizedDescription]; 221 | } 222 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"出错了" andMessage:msg]; 223 | 224 | [alertView addButtonWithTitle:@"确定" 225 | type:SIAlertViewButtonTypeCancel 226 | handler:^(SIAlertView *alert) { 227 | }]; 228 | 229 | alertView.transitionStyle = SIAlertViewTransitionStyleDropDown; 230 | 231 | [alertView show]; 232 | } 233 | 234 | 235 | }]; 236 | }else if([scheme hasPrefix:@"http"]){ 237 | 238 | NSString *storeId=[VZM storeIdOfURL:content]; 239 | if (storeId) { 240 | 241 | 242 | SKStoreProductViewController *storeProductViewController = [[SKStoreProductViewController alloc] init]; 243 | // Configure View Controller 244 | [storeProductViewController setDelegate:(id)self]; 245 | [storeProductViewController loadProductWithParameters:@{SKStoreProductParameterITunesItemIdentifier : storeId} 246 | 247 | completionBlock:^(BOOL result, NSError *error) { 248 | if (error) { 249 | NSLog(@"Error %@ with User Info %@.", error, [error userInfo]); 250 | 251 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"出错了" andMessage:[error localizedDescription]]; 252 | 253 | [alertView addButtonWithTitle:@"确定" 254 | type:SIAlertViewButtonTypeCancel 255 | handler:^(SIAlertView *alert) { 256 | 257 | }]; 258 | 259 | alertView.transitionStyle = SIAlertViewTransitionStyleDropDown; 260 | 261 | [alertView show]; 262 | 263 | } else { 264 | // Present Store Product View Controller 265 | [self presentViewController:storeProductViewController animated:YES completion:nil]; 266 | } 267 | ws.view.userInteractionEnabled=YES; 268 | ws.refreshView.infinite=NO; 269 | }]; 270 | 271 | return; 272 | } 273 | 274 | 275 | VZWebViewC *webc=[[VZWebViewC alloc] init]; 276 | 277 | [webc loadURL:content]; 278 | 279 | [self.navigationController pushViewController:webc animated:YES]; 280 | 281 | self.view.userInteractionEnabled=YES; 282 | self.refreshView.infinite=NO; 283 | 284 | } 285 | } 286 | 287 | /* 288 | // Override to support conditional editing of the table view. 289 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 290 | { 291 | // Return NO if you do not want the specified item to be editable. 292 | return YES; 293 | } 294 | */ 295 | 296 | /* 297 | // Override to support editing the table view. 298 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 299 | { 300 | if (editingStyle == UITableViewCellEditingStyleDelete) { 301 | // Delete the row from the data source 302 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 303 | } 304 | else if (editingStyle == UITableViewCellEditingStyleInsert) { 305 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 306 | } 307 | } 308 | */ 309 | 310 | /* 311 | // Override to support rearranging the table view. 312 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 313 | { 314 | } 315 | */ 316 | 317 | /* 318 | // Override to support conditional rearranging of the table view. 319 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 320 | { 321 | // Return NO if you do not want the item to be re-orderable. 322 | return YES; 323 | } 324 | */ 325 | 326 | /* 327 | #pragma mark - Navigation 328 | 329 | // In a story board-based application, you will often want to do a little preparation before navigation 330 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 331 | { 332 | // Get the new view controller using [segue destinationViewController]. 333 | // Pass the selected object to the new view controller. 334 | } 335 | 336 | */ 337 | 338 | 339 | - (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController { 340 | [self dismissViewControllerAnimated:YES completion:nil]; 341 | } 342 | @end 343 | -------------------------------------------------------------------------------- /VZ/VZWebViewC.h: -------------------------------------------------------------------------------- 1 | // 2 | // VZWebViewC.h 3 | // VZ 4 | // 5 | // Created by Travis on 14-1-7. 6 | // Copyright (c) 2014年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import 13 | 14 | @interface VZWebViewC : UIViewController 15 | @property(nonatomic,strong) UIWebView *webView; 16 | 17 | -(void)loadURL:(NSString*)url; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /VZ/VZWebViewC.m: -------------------------------------------------------------------------------- 1 | // 2 | // VZWebViewC.m 3 | // VZ 4 | // 5 | // Created by Travis on 14-1-7. 6 | // Copyright (c) 2014年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import "VZWebViewC.h" 10 | #import "VZProgressView.h" 11 | 12 | 13 | @interface VZWebViewC () 14 | @property(nonatomic,strong) VZProgressView *refreshView; 15 | @end 16 | 17 | @implementation VZWebViewC 18 | 19 | 20 | - (id)init 21 | { 22 | self = [super init]; 23 | if (self) { 24 | self.webView=[[UIWebView alloc] initWithFrame:self.view.bounds]; 25 | [self.view addSubview:self.webView]; 26 | 27 | self.webView.delegate=self; 28 | 29 | self.webView.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 30 | } 31 | return self; 32 | } 33 | 34 | - (void)viewDidLoad 35 | { 36 | [super viewDidLoad]; 37 | 38 | 39 | self.navigationItem.titleView=self.refreshView=[VZProgressView new]; 40 | self.refreshView.progress=1; 41 | 42 | } 43 | 44 | 45 | -(void)loadURL:(NSString*)url{ 46 | NSURLRequest *req=[NSURLRequest requestWithURL:[NSURL URLWithString:url]]; 47 | [self.webView loadRequest:req]; 48 | } 49 | 50 | -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ 51 | NSURL *url=request.URL; 52 | if ([url.host hasPrefix:@"itunes.apple.com"]) { 53 | NSRegularExpression *re=[NSRegularExpression regularExpressionWithPattern:@"id([0-9]{8,})" options:0 error:nil]; 54 | NSTextCheckingResult *result= [re firstMatchInString:url.path options:NSMatchingReportCompletion range:NSMakeRange(0, url.path.length)]; 55 | 56 | if (result) { 57 | NSString *storeId=[url.path substringWithRange:[result rangeAtIndex:1]]; 58 | if (storeId) { 59 | __weak typeof(self) ws=self; 60 | 61 | SKStoreProductViewController *storeProductViewController = [[SKStoreProductViewController alloc] init]; 62 | // Configure View Controller 63 | [storeProductViewController setDelegate:(id)self]; 64 | [storeProductViewController loadProductWithParameters:@{SKStoreProductParameterITunesItemIdentifier : storeId} 65 | 66 | completionBlock:^(BOOL result, NSError *error) { 67 | if (error) { 68 | NSLog(@"Error %@ with User Info %@.", error, [error userInfo]); 69 | 70 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"出错了" andMessage:[error localizedDescription]]; 71 | 72 | [alertView addButtonWithTitle:@"确定" 73 | type:SIAlertViewButtonTypeCancel 74 | handler:^(SIAlertView *alert) { 75 | [ws dismissViewControllerAnimated:YES completion:nil]; 76 | }]; 77 | 78 | alertView.transitionStyle = SIAlertViewTransitionStyleDropDown; 79 | 80 | [alertView show]; 81 | 82 | } else { 83 | // Present Store Product View Controller 84 | [ws presentViewController:storeProductViewController animated:YES completion:nil]; 85 | } 86 | 87 | ws.refreshView.infinite=NO; 88 | }]; 89 | 90 | self.refreshView.infinite=YES; 91 | return NO; 92 | } 93 | } 94 | 95 | } 96 | 97 | return YES; 98 | } 99 | 100 | -(void)webViewDidStartLoad:(UIWebView *)webView{ 101 | self.refreshView.infinite=YES; 102 | } 103 | 104 | -(void)webViewDidFinishLoad:(UIWebView *)webView{ 105 | self.refreshView.infinite=NO; 106 | } 107 | 108 | -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ 109 | self.refreshView.infinite=NO; 110 | 111 | SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"出错了" andMessage:[error localizedDescription]]; 112 | 113 | [alertView addButtonWithTitle:@"确定" 114 | type:SIAlertViewButtonTypeCancel 115 | handler:^(SIAlertView *alert) { 116 | 117 | }]; 118 | 119 | alertView.transitionStyle = SIAlertViewTransitionStyleDropDown; 120 | 121 | [alertView show]; 122 | } 123 | 124 | - (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController { 125 | [self dismissViewControllerAnimated:YES completion:nil]; 126 | } 127 | @end 128 | -------------------------------------------------------------------------------- /VZ/all@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/all@2x.png -------------------------------------------------------------------------------- /VZ/arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/arrow@2x.png -------------------------------------------------------------------------------- /VZ/bg2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/bg2@2x.png -------------------------------------------------------------------------------- /VZ/bg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/bg@2x.png -------------------------------------------------------------------------------- /VZ/chatBg2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/chatBg2@2x.png -------------------------------------------------------------------------------- /VZ/chatBg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/chatBg@2x.png -------------------------------------------------------------------------------- /VZ/close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/close@2x.png -------------------------------------------------------------------------------- /VZ/deal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/deal.png -------------------------------------------------------------------------------- /VZ/deal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/deal@2x.png -------------------------------------------------------------------------------- /VZ/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /VZ/fav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/fav.png -------------------------------------------------------------------------------- /VZ/fav@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/fav@2x.png -------------------------------------------------------------------------------- /VZ/geo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/geo@2x.png -------------------------------------------------------------------------------- /VZ/head@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/head@2x.png -------------------------------------------------------------------------------- /VZ/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/home.png -------------------------------------------------------------------------------- /VZ/home@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/home@2x.png -------------------------------------------------------------------------------- /VZ/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // VZ 4 | // 5 | // Created by Travis on 13-10-19. 6 | // Copyright (c) 2013年 Plumn LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "VZAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([VZAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /VZ/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/map.png -------------------------------------------------------------------------------- /VZ/map@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/map@2x.png -------------------------------------------------------------------------------- /VZ/navBg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/navBg@2x.png -------------------------------------------------------------------------------- /VZ/near@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/near@2x.png -------------------------------------------------------------------------------- /VZ/pics@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/pics@2x.png -------------------------------------------------------------------------------- /VZ/req@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/req@2x.png -------------------------------------------------------------------------------- /VZ/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/search.png -------------------------------------------------------------------------------- /VZ/search@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/search@2x.png -------------------------------------------------------------------------------- /VZ/searchClose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/searchClose.png -------------------------------------------------------------------------------- /VZ/searchClose@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/searchClose@2x.png -------------------------------------------------------------------------------- /VZ/settings@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/settings@2x.png -------------------------------------------------------------------------------- /VZ/spam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/spam.png -------------------------------------------------------------------------------- /VZ/spam@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/spam@2x.png -------------------------------------------------------------------------------- /VZ/trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/trash.png -------------------------------------------------------------------------------- /VZ/trash@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trawor/VZ/0f633a2448b0a545763b75efc19b39cd9fa2ad79/VZ/trash@2x.png -------------------------------------------------------------------------------- /VZ/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | "CFBundleDisplayName" ="微转"; --------------------------------------------------------------------------------