Commit e8d0319d09bcc08b24ad3a3d8e7be07c421d8cea
Merge branch 'master' of bj.gitlab.cnlive.com:ios-team/LiveVideoCloud
Showing
15 changed files
with
1582 additions
and
18 deletions
LiveVideoCloud/LiveVideoCloud.xcodeproj/project.pbxproj
| ... | ... | @@ -44,6 +44,9 @@ |
| 44 | 44 | 81A4831A1E88E19C0097A80A /* LVCMoreProgramViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A483191E88E19C0097A80A /* LVCMoreProgramViewController.m */; }; |
| 45 | 45 | 81A4831D1E88E1EB0097A80A /* LVCMoreSortTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A4831C1E88E1EB0097A80A /* LVCMoreSortTableViewCell.m */; }; |
| 46 | 46 | 81A483201E88F4BF0097A80A /* LVCProgramModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 81A4831F1E88F4BF0097A80A /* LVCProgramModel.m */; }; |
| 47 | + 81F1C8381E8BBDDA0085C2B8 /* MHPagingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81F1C8371E8BBDDA0085C2B8 /* MHPagingScrollView.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; | |
| 48 | + 81F1C83D1E8BBDE40085C2B8 /* V8HorizontalPickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 81F1C83B1E8BBDE40085C2B8 /* V8HorizontalPickerView.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; | |
| 49 | + 81F1C8401E8BC5CC0085C2B8 /* NSArray+Safety.m in Sources */ = {isa = PBXBuildFile; fileRef = 81F1C83F1E8BC5CC0085C2B8 /* NSArray+Safety.m */; }; | |
| 47 | 50 | 81FB5B3C1E7A6FFC00F98E1D /* SevenSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 81FB5B3B1E7A6FFC00F98E1D /* SevenSwitch.m */; }; |
| 48 | 51 | D2029B861E6EAAA50027CD92 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D2029B851E6EAAA50027CD92 /* main.m */; }; |
| 49 | 52 | D2029B911E6EAAA50027CD92 /* animation.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D2029B901E6EAAA50027CD92 /* animation.xcassets */; }; |
| ... | ... | @@ -319,6 +322,13 @@ |
| 319 | 322 | 81A4831C1E88E1EB0097A80A /* LVCMoreSortTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCMoreSortTableViewCell.m; sourceTree = "<group>"; }; |
| 320 | 323 | 81A4831E1E88F4BF0097A80A /* LVCProgramModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LVCProgramModel.h; sourceTree = "<group>"; }; |
| 321 | 324 | 81A4831F1E88F4BF0097A80A /* LVCProgramModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LVCProgramModel.m; sourceTree = "<group>"; }; |
| 325 | + 81F1C8361E8BBDDA0085C2B8 /* MHPagingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHPagingScrollView.h; sourceTree = "<group>"; }; | |
| 326 | + 81F1C8371E8BBDDA0085C2B8 /* MHPagingScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHPagingScrollView.m; sourceTree = "<group>"; }; | |
| 327 | + 81F1C83A1E8BBDE40085C2B8 /* V8HorizontalPickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = V8HorizontalPickerView.h; sourceTree = "<group>"; }; | |
| 328 | + 81F1C83B1E8BBDE40085C2B8 /* V8HorizontalPickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = V8HorizontalPickerView.m; sourceTree = "<group>"; }; | |
| 329 | + 81F1C83C1E8BBDE40085C2B8 /* V8HorizontalPickerViewProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = V8HorizontalPickerViewProtocol.h; sourceTree = "<group>"; }; | |
| 330 | + 81F1C83E1E8BC5CC0085C2B8 /* NSArray+Safety.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Safety.h"; sourceTree = "<group>"; }; | |
| 331 | + 81F1C83F1E8BC5CC0085C2B8 /* NSArray+Safety.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Safety.m"; sourceTree = "<group>"; }; | |
| 322 | 332 | 81FB5B3A1E7A6FFC00F98E1D /* SevenSwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SevenSwitch.h; sourceTree = "<group>"; }; |
| 323 | 333 | 81FB5B3B1E7A6FFC00F98E1D /* SevenSwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SevenSwitch.m; sourceTree = "<group>"; }; |
| 324 | 334 | D2029B811E6EAAA50027CD92 /* LiveVideoCloud.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LiveVideoCloud.app; sourceTree = BUILT_PRODUCTS_DIR; }; |
| ... | ... | @@ -770,6 +780,25 @@ |
| 770 | 780 | path = Model; |
| 771 | 781 | sourceTree = "<group>"; |
| 772 | 782 | }; |
| 783 | + 81F1C8351E8BBDDA0085C2B8 /* MHPagingScrollView */ = { | |
| 784 | + isa = PBXGroup; | |
| 785 | + children = ( | |
| 786 | + 81F1C8361E8BBDDA0085C2B8 /* MHPagingScrollView.h */, | |
| 787 | + 81F1C8371E8BBDDA0085C2B8 /* MHPagingScrollView.m */, | |
| 788 | + ); | |
| 789 | + path = MHPagingScrollView; | |
| 790 | + sourceTree = "<group>"; | |
| 791 | + }; | |
| 792 | + 81F1C8391E8BBDE40085C2B8 /* V8HorizontalPickerView */ = { | |
| 793 | + isa = PBXGroup; | |
| 794 | + children = ( | |
| 795 | + 81F1C83A1E8BBDE40085C2B8 /* V8HorizontalPickerView.h */, | |
| 796 | + 81F1C83B1E8BBDE40085C2B8 /* V8HorizontalPickerView.m */, | |
| 797 | + 81F1C83C1E8BBDE40085C2B8 /* V8HorizontalPickerViewProtocol.h */, | |
| 798 | + ); | |
| 799 | + path = V8HorizontalPickerView; | |
| 800 | + sourceTree = "<group>"; | |
| 801 | + }; | |
| 773 | 802 | 81FB5B391E7A6FFC00F98E1D /* SevenSwitch */ = { |
| 774 | 803 | isa = PBXGroup; |
| 775 | 804 | children = ( |
| ... | ... | @@ -903,6 +932,8 @@ |
| 903 | 932 | D2029BD41E6EADE10027CD92 /* SDK */ = { |
| 904 | 933 | isa = PBXGroup; |
| 905 | 934 | children = ( |
| 935 | + 81F1C8391E8BBDE40085C2B8 /* V8HorizontalPickerView */, | |
| 936 | + 81F1C8351E8BBDDA0085C2B8 /* MHPagingScrollView */, | |
| 906 | 937 | 81FB5B391E7A6FFC00F98E1D /* SevenSwitch */, |
| 907 | 938 | 810B64E41E779B1F00133E15 /* Masonry */, |
| 908 | 939 | D2029BD51E6EADE10027CD92 /* AFNetworking */, |
| ... | ... | @@ -1278,6 +1309,8 @@ |
| 1278 | 1309 | D2029CDD1E6EAE2E0027CD92 /* Category */ = { |
| 1279 | 1310 | isa = PBXGroup; |
| 1280 | 1311 | children = ( |
| 1312 | + 81F1C83E1E8BC5CC0085C2B8 /* NSArray+Safety.h */, | |
| 1313 | + 81F1C83F1E8BC5CC0085C2B8 /* NSArray+Safety.m */, | |
| 1281 | 1314 | 81A483061E88B6140097A80A /* UIView+ViewController.h */, |
| 1282 | 1315 | 81A483071E88B6140097A80A /* UIView+ViewController.m */, |
| 1283 | 1316 | D24571561E8393EB00AA85D6 /* UIImageView+ZXExtension.h */, |
| ... | ... | @@ -1894,6 +1927,7 @@ |
| 1894 | 1927 | files = ( |
| 1895 | 1928 | D2029CC31E6EADE10027CD92 /* UIImageView+HighlightedWebCache.m in Sources */, |
| 1896 | 1929 | D22830FF1E77C69E00627701 /* GiftListView.m in Sources */, |
| 1930 | + 81F1C83D1E8BBDE40085C2B8 /* V8HorizontalPickerView.m in Sources */, | |
| 1897 | 1931 | D2029CC01E6EADE10027CD92 /* UIImage+GIF.m in Sources */, |
| 1898 | 1932 | D25BF8831E7F775F007FB138 /* LVCUGCPlayerLoadingView.m in Sources */, |
| 1899 | 1933 | 81A4831A1E88E19C0097A80A /* LVCMoreProgramViewController.m in Sources */, |
| ... | ... | @@ -1918,6 +1952,7 @@ |
| 1918 | 1952 | 8130911E1E84C0F0005F0BFF /* LVCMessage.m in Sources */, |
| 1919 | 1953 | D23696841E7FC6A900E4BF71 /* chatListCell.m in Sources */, |
| 1920 | 1954 | D2029CAF1E6EADE10027CD92 /* MJRefreshStateHeader.m in Sources */, |
| 1955 | + 81F1C8401E8BC5CC0085C2B8 /* NSArray+Safety.m in Sources */, | |
| 1921 | 1956 | D2A089EE1E8A336A0071412C /* LiveLIstService.m in Sources */, |
| 1922 | 1957 | D2029C941E6EADE10027CD92 /* UIRefreshControl+AFNetworking.m in Sources */, |
| 1923 | 1958 | D2029C911E6EADE10027CD92 /* UIButton+AFNetworking.m in Sources */, |
| ... | ... | @@ -1945,6 +1980,7 @@ |
| 1945 | 1980 | D2029CCE1E6EADE10027CD92 /* SearchRecomListModel.m in Sources */, |
| 1946 | 1981 | D2029CA11E6EADE10027CD92 /* NSString+MJExtension.m in Sources */, |
| 1947 | 1982 | D2029BCB1E6EADD70027CD92 /* BaseTableViewCell.m in Sources */, |
| 1983 | + 81F1C8381E8BBDDA0085C2B8 /* MHPagingScrollView.m in Sources */, | |
| 1948 | 1984 | D2029CAA1E6EADE10027CD92 /* MJRefreshBackGifFooter.m in Sources */, |
| 1949 | 1985 | D217A24B1E7B76C7003B44CB /* PresentViewCell.m in Sources */, |
| 1950 | 1986 | D2029C9B1E6EADE10027CD92 /* MJPropertyKey.m in Sources */, |
| ... | ... | @@ -2208,6 +2244,7 @@ |
| 2208 | 2244 | buildSettings = { |
| 2209 | 2245 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
| 2210 | 2246 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; |
| 2247 | + CLANG_ENABLE_OBJC_WEAK = YES; | |
| 2211 | 2248 | DEVELOPMENT_TEAM = 94X49GG3ZW; |
| 2212 | 2249 | FRAMEWORK_SEARCH_PATHS = ( |
| 2213 | 2250 | "$(inherited)", |
| ... | ... | @@ -2221,6 +2258,7 @@ |
| 2221 | 2258 | "$(inherited)", |
| 2222 | 2259 | "$(PROJECT_DIR)/LiveVideoCloud/Classes/Sections/InteractionSections/Gift/GiftResource", |
| 2223 | 2260 | ); |
| 2261 | + OTHER_LDFLAGS = ""; | |
| 2224 | 2262 | PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.shixunyun; |
| 2225 | 2263 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 2226 | 2264 | }; |
| ... | ... | @@ -2231,6 +2269,7 @@ |
| 2231 | 2269 | buildSettings = { |
| 2232 | 2270 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
| 2233 | 2271 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; |
| 2272 | + CLANG_ENABLE_OBJC_WEAK = YES; | |
| 2234 | 2273 | DEVELOPMENT_TEAM = 94X49GG3ZW; |
| 2235 | 2274 | FRAMEWORK_SEARCH_PATHS = ( |
| 2236 | 2275 | "$(inherited)", |
| ... | ... | @@ -2244,6 +2283,7 @@ |
| 2244 | 2283 | "$(inherited)", |
| 2245 | 2284 | "$(PROJECT_DIR)/LiveVideoCloud/Classes/Sections/InteractionSections/Gift/GiftResource", |
| 2246 | 2285 | ); |
| 2286 | + OTHER_LDFLAGS = ""; | |
| 2247 | 2287 | PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.shixunyun; |
| 2248 | 2288 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 2249 | 2289 | }; | ... | ... |
LiveVideoCloud/LiveVideoCloud/AppCustoms/Main/ZXNavigationController.m
| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | self.interactivePopGestureRecognizer.delegate = self; |
| 23 | 23 | self.interactivePopGestureRecognizer.enabled = YES; |
| 24 | 24 | |
| 25 | - [[UINavigationBar appearance] setBarTintColor:[UIColor blackColorZX]]; | |
| 25 | + [[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]]; | |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | 28 | /** | ... | ... |
LiveVideoCloud/LiveVideoCloud/AppDelegate/AppDelegate.m
| ... | ... | @@ -31,23 +31,23 @@ |
| 31 | 31 | //初始化聊天SDK并连接服务器 |
| 32 | 32 | [[CNLiveChatManager sharedCNLiveChatManager] initWithAppKey:AppKey appId:AppId]; |
| 33 | 33 | |
| 34 | - [[CNLiveChatManager sharedCNLiveChatManager] connectServerSuccess:^{ | |
| 35 | - NSLog(@"连接服务器-----success"); | |
| 36 | - } error:^(CNLiveChatConnectErrorCode errors) { | |
| 37 | - NSLog(@"连接服务器失败-----%ld", errors); | |
| 38 | - }]; | |
| 39 | - /* | |
| 40 | - */ | |
| 41 | - // 20170327 20170328 | |
| 42 | 34 | /* |
| 43 | - CNLiveChatUserInfo *userInfo = [[CNLiveChatUserInfo alloc] initWithUserId:@"20170328" name:@"20170328" portrait:@""]; | |
| 44 | - [[CNLiveChatManager sharedCNLiveChatManager] loginServer:userInfo success:^(NSString *userId) { | |
| 35 | + [[CNLiveChatManager sharedCNLiveChatManager] connectServerSuccess:^{ | |
| 45 | 36 | NSLog(@"连接服务器-----success"); |
| 46 | - | |
| 47 | 37 | } error:^(CNLiveChatConnectErrorCode errors) { |
| 48 | 38 | NSLog(@"连接服务器失败-----%ld", errors); |
| 49 | 39 | }]; |
| 50 | 40 | */ |
| 41 | + // 20170327 20170328 | |
| 42 | + /* | |
| 43 | + */ | |
| 44 | + CNLiveChatUserInfo *userInfo = [[CNLiveChatUserInfo alloc] initWithUserId:@"20170328" name:@"20170328" portrait:@""]; | |
| 45 | + [[CNLiveChatManager sharedCNLiveChatManager] loginServer:userInfo success:^(NSString *userId) { | |
| 46 | + NSLog(@"连接服务器-----success"); | |
| 47 | + | |
| 48 | + } error:^(CNLiveChatConnectErrorCode errors) { | |
| 49 | + NSLog(@"连接服务器失败-----%ld", errors); | |
| 50 | + }]; | |
| 51 | 51 | [self.window makeKeyAndVisible]; |
| 52 | 52 | |
| 53 | 53 | return YES; | ... | ... |
LiveVideoCloud/LiveVideoCloud/Classes/SDK/MHPagingScrollView/MHPagingScrollView.h
0 → 100755
| 1 | + | |
| 2 | +#import <Foundation/Foundation.h> | |
| 3 | +#import <UIKit/UIKit.h> | |
| 4 | +@class MHPagingScrollView; | |
| 5 | + | |
| 6 | +/* | |
| 7 | + * Delegate protocol for MHPagingScrollView. | |
| 8 | + */ | |
| 9 | +@protocol MHPagingScrollViewDelegate <NSObject> | |
| 10 | + | |
| 11 | +/* | |
| 12 | + * Asks the delegate to return the number of pages. | |
| 13 | + */ | |
| 14 | +- (NSUInteger)numberOfPagesInPagingScrollView:(MHPagingScrollView *)pagingScrollView; | |
| 15 | + | |
| 16 | +/* | |
| 17 | + * Asks the delegate for a page to insert. The delegate should ask for a | |
| 18 | + * reusable view using dequeueReusablePageView. | |
| 19 | + */ | |
| 20 | +- (UIView *)pagingScrollView:(MHPagingScrollView *)pagingScrollView pageForIndex:(NSUInteger)index; | |
| 21 | + | |
| 22 | +@end | |
| 23 | + | |
| 24 | +/* | |
| 25 | + * A paging scroll view that employs a reusable page mechanism like UITableView. | |
| 26 | + * | |
| 27 | + * MHPagingScrollView allows you to show partial previews of the pages to the | |
| 28 | + * left and right of the current page. The bounds of the scroll view always | |
| 29 | + * correspond to a single page. To allow these previews, make the scroll view | |
| 30 | + * smaller to make room for the preview pages and set the previewInsets | |
| 31 | + * property. | |
| 32 | + */ | |
| 33 | +@interface MHPagingScrollView : UIScrollView | |
| 34 | + | |
| 35 | +/* The delegate for paging events. */ | |
| 36 | +@property (nonatomic, weak) id <MHPagingScrollViewDelegate> pagingDelegate; | |
| 37 | + | |
| 38 | +/* The width of the preview pages. */ | |
| 39 | +@property (nonatomic, assign) UIEdgeInsets previewInsets; | |
| 40 | + | |
| 41 | +/* set prepare, default is 0 */ | |
| 42 | +@property (nonatomic, assign) NSUInteger rightPrepareCount; | |
| 43 | +@property (nonatomic, assign) NSUInteger leftPrepareCount; | |
| 44 | + | |
| 45 | +//- (void)refreshPage; | |
| 46 | + | |
| 47 | +/* | |
| 48 | + * Makes the page at the requested index visible. | |
| 49 | + */ | |
| 50 | +- (void)selectPageAtIndex:(NSUInteger)index animated:(BOOL)animated; | |
| 51 | + | |
| 52 | +/* | |
| 53 | + * Returns the index of the page that is currently visible. | |
| 54 | + */ | |
| 55 | +- (NSUInteger)indexOfSelectedPage; | |
| 56 | + | |
| 57 | +/* | |
| 58 | + * Returns a reusable UIView object. | |
| 59 | + */ | |
| 60 | +- (UIView *)dequeueReusablePage; | |
| 61 | + | |
| 62 | +- (UIView *)dequeueReusablePageWithIdentify:(NSString *)identify; | |
| 63 | + | |
| 64 | +/* | |
| 65 | + * Reloads the pages. Call this method when the number of pages has changed. | |
| 66 | + */ | |
| 67 | +- (void)reloadPages; | |
| 68 | + | |
| 69 | +/* | |
| 70 | + * Call this from your view controller's UIScrollViewDelegate. | |
| 71 | + */ | |
| 72 | +- (void)scrollViewDidScroll; | |
| 73 | + | |
| 74 | +/* | |
| 75 | + * Call this from your view controller's willRotateToInterfaceOrientation if | |
| 76 | + * you want to support autorotation. | |
| 77 | + */ | |
| 78 | +- (void)beforeRotation; | |
| 79 | + | |
| 80 | +/* | |
| 81 | + * Call this from your view controller's willAnimateRotationToInterfaceOrientation | |
| 82 | + * if you want to support autorotation. | |
| 83 | + */ | |
| 84 | +- (void)afterRotation; | |
| 85 | + | |
| 86 | +/* | |
| 87 | + * Call this from your view controller's didReceiveMemoryWarning. | |
| 88 | + */ | |
| 89 | +- (void)didReceiveMemoryWarning; | |
| 90 | + | |
| 91 | +@end | |
| 92 | + | |
| 93 | +@interface MHPagingScrollView (UNREUSE) | |
| 94 | + | |
| 95 | +/* | |
| 96 | + * Returns a UIView object by index. | |
| 97 | + */ | |
| 98 | +- (UIView *)pageViewByIndex:(NSInteger)index; | |
| 99 | + | |
| 100 | +/* | |
| 101 | + * Returns the select UIView object . | |
| 102 | + */ | |
| 103 | +- (UIView *)selectPageView; | |
| 104 | + | |
| 105 | +- (BOOL)isLoadedPageByIndex:(NSInteger)index; | |
| 106 | + | |
| 107 | +- (void)preLoadedPageView:(UIView*)view index:(NSInteger)index; | |
| 108 | + | |
| 109 | +@end | ... | ... |
LiveVideoCloud/LiveVideoCloud/Classes/SDK/MHPagingScrollView/MHPagingScrollView.m
0 → 100755
| 1 | + | |
| 2 | +#import "MHPagingScrollView.h" | |
| 3 | + | |
| 4 | +@interface MHPage : NSObject | |
| 5 | + | |
| 6 | +@property (nonatomic, strong) UIView *view; | |
| 7 | +@property (nonatomic, assign) NSUInteger index; | |
| 8 | + | |
| 9 | +@end | |
| 10 | + | |
| 11 | +@implementation MHPage | |
| 12 | + | |
| 13 | +@end | |
| 14 | + | |
| 15 | +@implementation MHPagingScrollView | |
| 16 | +{ | |
| 17 | + NSMutableSet *_recycledPages; | |
| 18 | + NSMutableSet *_visiblePages; | |
| 19 | + NSUInteger _firstVisiblePageIndexBeforeRotation; // for autorotation | |
| 20 | + CGFloat _percentScrolledIntoFirstVisiblePage; | |
| 21 | +} | |
| 22 | + | |
| 23 | +- (void)commonInit | |
| 24 | +{ | |
| 25 | + _recycledPages = [[NSMutableSet alloc] init]; | |
| 26 | + _visiblePages = [[NSMutableSet alloc] init]; | |
| 27 | + | |
| 28 | + self.pagingEnabled = YES; | |
| 29 | + self.showsVerticalScrollIndicator = NO; | |
| 30 | + self.showsHorizontalScrollIndicator = NO; | |
| 31 | + self.contentOffset = CGPointZero; | |
| 32 | +} | |
| 33 | + | |
| 34 | +- (id)initWithFrame:(CGRect)frame | |
| 35 | +{ | |
| 36 | + if ((self = [super initWithFrame:frame])) | |
| 37 | + { | |
| 38 | + [self commonInit]; | |
| 39 | + } | |
| 40 | + return self; | |
| 41 | +} | |
| 42 | + | |
| 43 | +- (id)initWithCoder:(NSCoder *)aDecoder | |
| 44 | +{ | |
| 45 | + if ((self = [super initWithCoder:aDecoder])) | |
| 46 | + { | |
| 47 | + [self commonInit]; | |
| 48 | + } | |
| 49 | + return self; | |
| 50 | +} | |
| 51 | + | |
| 52 | +- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event | |
| 53 | +{ | |
| 54 | + // This allows for touch handling outside of the scroll view's bounds. | |
| 55 | + | |
| 56 | + CGPoint parentLocation = [self convertPoint:point toView:self.superview]; | |
| 57 | + | |
| 58 | + CGRect responseRect = self.frame; | |
| 59 | + responseRect.origin.x -= _previewInsets.left; | |
| 60 | + responseRect.origin.y -= _previewInsets.top; | |
| 61 | + responseRect.size.width += (_previewInsets.left + _previewInsets.right); | |
| 62 | + responseRect.size.height += (_previewInsets.top + _previewInsets.bottom); | |
| 63 | + | |
| 64 | + return CGRectContainsPoint(responseRect, parentLocation); | |
| 65 | +} | |
| 66 | + | |
| 67 | +- (void)selectPageAtIndex:(NSUInteger)index animated:(BOOL)animated | |
| 68 | +{ | |
| 69 | + if (animated) { | |
| 70 | + | |
| 71 | + [UIView beginAnimations:nil context:NULL]; | |
| 72 | + [UIView setAnimationDuration:0.3f]; | |
| 73 | + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; | |
| 74 | + } | |
| 75 | + | |
| 76 | + self.contentOffset = CGPointMake(self.bounds.size.width * index, 0); | |
| 77 | + if (animated) { | |
| 78 | + | |
| 79 | + [UIView commitAnimations]; | |
| 80 | + } | |
| 81 | +} | |
| 82 | + | |
| 83 | +- (NSUInteger)indexOfSelectedPage | |
| 84 | +{ | |
| 85 | + CGFloat width = self.bounds.size.width; | |
| 86 | + int currentPage = (self.contentOffset.x + width/2.0f) / width; | |
| 87 | + return currentPage; | |
| 88 | +} | |
| 89 | + | |
| 90 | +- (NSUInteger)numberOfPages | |
| 91 | +{ | |
| 92 | + return [_pagingDelegate numberOfPagesInPagingScrollView:self]; | |
| 93 | +} | |
| 94 | + | |
| 95 | +- (CGSize)contentSizeForPagingScrollView | |
| 96 | +{ | |
| 97 | + CGRect rect = self.bounds; | |
| 98 | + return CGSizeMake(rect.size.width * [self numberOfPages], rect.size.height); | |
| 99 | +} | |
| 100 | + | |
| 101 | +- (BOOL)isDisplayingPageForIndex:(NSUInteger)index | |
| 102 | +{ | |
| 103 | + for (MHPage *page in _visiblePages) | |
| 104 | + { | |
| 105 | + if (page.index == index) | |
| 106 | + return YES; | |
| 107 | + } | |
| 108 | + return NO; | |
| 109 | +} | |
| 110 | + | |
| 111 | +- (UIView *)dequeueReusablePage | |
| 112 | +{ | |
| 113 | + MHPage *page = [_recycledPages anyObject]; | |
| 114 | + if (page != nil) | |
| 115 | + { | |
| 116 | + UIView *view = page.view; | |
| 117 | + [_recycledPages removeObject:page]; | |
| 118 | + return view; | |
| 119 | + } | |
| 120 | + return nil; | |
| 121 | +} | |
| 122 | + | |
| 123 | +- (UIView *)dequeueReusablePageWithIdentify:(NSString *)identify | |
| 124 | +{ | |
| 125 | + for (MHPage *page in _recycledPages) { | |
| 126 | + if (page != nil) { | |
| 127 | + if ([[NSString stringWithFormat:@"%ld", (long)page.view.tag] isEqualToString:identify]) { | |
| 128 | + UIView *view = page.view; | |
| 129 | + [_recycledPages removeObject:page]; | |
| 130 | + return view; | |
| 131 | + } | |
| 132 | + } | |
| 133 | + } | |
| 134 | + return nil; | |
| 135 | +} | |
| 136 | + | |
| 137 | +- (CGRect)frameForPageAtIndex:(NSUInteger)index | |
| 138 | +{ | |
| 139 | + CGRect rect = self.bounds; | |
| 140 | + rect.origin.x = rect.size.width * index; | |
| 141 | + return rect; | |
| 142 | +} | |
| 143 | + | |
| 144 | +- (void)tilePages | |
| 145 | +{ | |
| 146 | + CGRect visibleBounds = self.bounds; | |
| 147 | + CGFloat pageWidth = CGRectGetWidth(visibleBounds); | |
| 148 | + visibleBounds.origin.x -= _previewInsets.left; | |
| 149 | + visibleBounds.size.width += (_previewInsets.left + _previewInsets.right); | |
| 150 | + | |
| 151 | + int firstNeededPageIndex = floorf(CGRectGetMinX(visibleBounds) / pageWidth)-self.leftPrepareCount; | |
| 152 | + int lastNeededPageIndex = floorf((CGRectGetMaxX(visibleBounds) - 1.0f) / pageWidth)+self.rightPrepareCount; | |
| 153 | + firstNeededPageIndex = MAX(firstNeededPageIndex, 0); | |
| 154 | + lastNeededPageIndex = MIN(lastNeededPageIndex, (int)[self numberOfPages] - 1); | |
| 155 | + | |
| 156 | + for (MHPage *page in _visiblePages) | |
| 157 | + { | |
| 158 | + if ((int)page.index < firstNeededPageIndex || (int)page.index > lastNeededPageIndex) | |
| 159 | + { | |
| 160 | + [_recycledPages addObject:page]; | |
| 161 | + [page.view removeFromSuperview]; | |
| 162 | + } | |
| 163 | + } | |
| 164 | + | |
| 165 | + [_visiblePages minusSet:_recycledPages]; | |
| 166 | + for (UIView *view in _recycledPages) { | |
| 167 | + if ([view isKindOfClass:[UIScrollView class]]) { | |
| 168 | + UIScrollView *scroll = (UIScrollView *)view; | |
| 169 | + scroll.scrollsToTop = NO; | |
| 170 | + } | |
| 171 | + } | |
| 172 | + | |
| 173 | + for (int i = firstNeededPageIndex; i <= lastNeededPageIndex; ++i) | |
| 174 | + { | |
| 175 | + if (![self isDisplayingPageForIndex:i]) | |
| 176 | + { | |
| 177 | + UIView *pageView = [_pagingDelegate pagingScrollView:self pageForIndex:i]; | |
| 178 | + if ([pageView isKindOfClass:[UIScrollView class]]) { | |
| 179 | + UIScrollView *scroll = (UIScrollView *)pageView; | |
| 180 | + scroll.scrollsToTop = YES; | |
| 181 | + } | |
| 182 | + pageView.frame = [self frameForPageAtIndex:i]; | |
| 183 | + pageView.autoresizingMask = UIViewAutoresizingFlexibleHeight; | |
| 184 | + [self addSubview:pageView]; | |
| 185 | + | |
| 186 | + MHPage *page = [[MHPage alloc] init]; | |
| 187 | + page.index = i; | |
| 188 | + page.view = pageView; | |
| 189 | + [_visiblePages addObject:page]; | |
| 190 | + } | |
| 191 | + } | |
| 192 | +} | |
| 193 | + | |
| 194 | +- (void)reloadPages | |
| 195 | +{ | |
| 196 | + self.contentSize = [self contentSizeForPagingScrollView]; | |
| 197 | + for (MHPage *page in _visiblePages) { | |
| 198 | + [page.view removeFromSuperview]; | |
| 199 | + } | |
| 200 | + for (MHPage *page in _recycledPages) { | |
| 201 | + [page.view removeFromSuperview]; | |
| 202 | + } | |
| 203 | + [_visiblePages removeAllObjects]; | |
| 204 | + [_recycledPages removeAllObjects]; | |
| 205 | + [self tilePages]; | |
| 206 | +} | |
| 207 | + | |
| 208 | +- (void)scrollViewDidScroll | |
| 209 | +{ | |
| 210 | + [self tilePages]; | |
| 211 | +} | |
| 212 | + | |
| 213 | +- (void)beforeRotation | |
| 214 | +{ | |
| 215 | + CGFloat offset = self.contentOffset.x; | |
| 216 | + CGFloat pageWidth = self.bounds.size.width; | |
| 217 | + | |
| 218 | + if (offset >= 0) | |
| 219 | + _firstVisiblePageIndexBeforeRotation = floorf(offset / pageWidth); | |
| 220 | + else | |
| 221 | + _firstVisiblePageIndexBeforeRotation = 0; | |
| 222 | + | |
| 223 | + _percentScrolledIntoFirstVisiblePage = offset / pageWidth - _firstVisiblePageIndexBeforeRotation; | |
| 224 | +} | |
| 225 | + | |
| 226 | +- (void)afterRotation | |
| 227 | +{ | |
| 228 | + self.contentSize = [self contentSizeForPagingScrollView]; | |
| 229 | + | |
| 230 | + for (MHPage *page in _visiblePages) | |
| 231 | + page.view.frame = [self frameForPageAtIndex:page.index]; | |
| 232 | + | |
| 233 | + CGFloat pageWidth = self.bounds.size.width; | |
| 234 | + CGFloat newOffset = (_firstVisiblePageIndexBeforeRotation + _percentScrolledIntoFirstVisiblePage) * pageWidth; | |
| 235 | + self.contentOffset = CGPointMake(newOffset, 0); | |
| 236 | +} | |
| 237 | + | |
| 238 | +- (void)didReceiveMemoryWarning | |
| 239 | +{ | |
| 240 | + [_recycledPages removeAllObjects]; | |
| 241 | +} | |
| 242 | + | |
| 243 | +@end | |
| 244 | + | |
| 245 | +@implementation MHPagingScrollView (UNREUSE) | |
| 246 | + | |
| 247 | +- (UIView *)pageViewByIndex:(NSInteger)index{ | |
| 248 | + for (MHPage* page in _recycledPages) { | |
| 249 | + if (page.index == index) { | |
| 250 | + UIView *view = page.view; | |
| 251 | + [_recycledPages removeObject:page]; | |
| 252 | + return view; | |
| 253 | + } | |
| 254 | + } | |
| 255 | + for (MHPage *page in _visiblePages) { | |
| 256 | + if (page.index == index) { | |
| 257 | + UIView *view = page.view; | |
| 258 | + return view; | |
| 259 | + } | |
| 260 | + } | |
| 261 | + return nil; | |
| 262 | +} | |
| 263 | + | |
| 264 | +- (UIView *)selectPageView{ | |
| 265 | + NSUInteger index = [self indexOfSelectedPage]; | |
| 266 | + for (MHPage *page in _visiblePages) { | |
| 267 | + if (page.index == index) { | |
| 268 | + UIView *view = page.view; | |
| 269 | + return view; | |
| 270 | + } | |
| 271 | + } | |
| 272 | + return nil; | |
| 273 | +} | |
| 274 | + | |
| 275 | +- (BOOL)isLoadedPageByIndex:(NSInteger)index{ | |
| 276 | + | |
| 277 | + for (MHPage* page in _recycledPages) { | |
| 278 | + if (page.index == index) { | |
| 279 | + return true; | |
| 280 | + } | |
| 281 | + } | |
| 282 | + for (MHPage *page in _visiblePages) { | |
| 283 | + if (page.index == index) { | |
| 284 | + return true; | |
| 285 | + } | |
| 286 | + } | |
| 287 | + return false; | |
| 288 | + | |
| 289 | +} | |
| 290 | + | |
| 291 | +- (void)preLoadedPageView:(UIView*)view index:(NSInteger)index{ | |
| 292 | + | |
| 293 | + MHPage *page = [[MHPage alloc] init]; | |
| 294 | + page.index = index; | |
| 295 | + page.view = view; | |
| 296 | + [_recycledPages addObject:page]; | |
| 297 | + | |
| 298 | +} | |
| 299 | + | |
| 300 | +- (void)refreshPage | |
| 301 | +{ | |
| 302 | + [_pagingDelegate pagingScrollView:self pageForIndex:0]; | |
| 303 | +} | |
| 304 | + | |
| 305 | +@end | |
| 0 | 306 | \ No newline at end of file | ... | ... |
LiveVideoCloud/LiveVideoCloud/Classes/SDK/V8HorizontalPickerView/V8HorizontalPickerView.h
0 → 100755
| 1 | +// | |
| 2 | +// V8HorizontalPickerView.h | |
| 3 | +// | |
| 4 | +// Created by Shawn Veader on 9/17/10. | |
| 5 | +// Copyright 2010 V8 Labs, LLC. All rights reserved. | |
| 6 | +// | |
| 7 | + | |
| 8 | +#import <UIKit/UIKit.h> | |
| 9 | +#import "V8HorizontalPickerViewProtocol.h" | |
| 10 | + | |
| 11 | +@interface V8HorizontalPickerView : UIView <UIScrollViewDelegate> { } | |
| 12 | + | |
| 13 | +// delegate and datasources to feed scroll view. this view only maintains a weak reference to these | |
| 14 | +@property (nonatomic, assign) id <V8HorizontalPickerViewDataSource> dataSource; | |
| 15 | +@property (nonatomic, assign) id <V8HorizontalPickerViewDelegate> delegate; | |
| 16 | + | |
| 17 | +@property (nonatomic, readonly) NSInteger numberOfElements; | |
| 18 | +@property (nonatomic, readonly) NSInteger currentSelectedIndex; | |
| 19 | + | |
| 20 | +// what font to use for the element labels? | |
| 21 | +@property (nonatomic, retain) UIFont *elementFont; | |
| 22 | + | |
| 23 | +// color of labels used in picker | |
| 24 | +@property (nonatomic, retain) UIColor *textColor; | |
| 25 | +@property (nonatomic, retain) UIColor *selectedTextColor; // color of current selected element | |
| 26 | + | |
| 27 | +// select bg image | |
| 28 | +@property (nonatomic, retain) UIImage *currentBgImage; | |
| 29 | +@property (nonatomic, retain) NSString *isChatRoom; | |
| 30 | + | |
| 31 | +// views to display on edges of picker (eg: gradients, etc) | |
| 32 | +@property (nonatomic, retain) UIView *leftEdgeView; | |
| 33 | +@property (nonatomic, retain) UIView *rightEdgeView; | |
| 34 | + | |
| 35 | +// views for left and right of scrolling area | |
| 36 | +@property (nonatomic, retain) UIView *leftScrollEdgeView; | |
| 37 | +@property (nonatomic, retain) UIView *rightScrollEdgeView; | |
| 38 | + | |
| 39 | +// padding for left/right scroll edge views | |
| 40 | +@property (nonatomic, assign) CGFloat scrollEdgeViewPadding; | |
| 41 | + | |
| 42 | +@property (nonatomic, assign) NSInteger elementPadding; | |
| 43 | +@property (nonatomic, retain) UIScrollView *scrollView; | |
| 44 | +@property (nonatomic, retain) NSMutableArray *elementWidths; | |
| 45 | + | |
| 46 | +@property (nonatomic, assign) BOOL clickElementEnable; | |
| 47 | + | |
| 48 | +@property (nonatomic, assign) BOOL plugins; | |
| 49 | +@property (nonatomic, assign) BOOL myVideos; | |
| 50 | +@property (nonatomic, assign) BOOL home; | |
| 51 | + | |
| 52 | +- (id)initWithFrame:(CGRect)frame plugins:(BOOL)plugins myVideos:(BOOL)myVideos; | |
| 53 | +- (id)initWithFrame:(CGRect)frame home:(BOOL)home; | |
| 54 | + | |
| 55 | +- (void)reloadData; | |
| 56 | +- (void)scrollToElement:(NSInteger)index animated:(BOOL)animate; | |
| 57 | +@end | |
| 58 | + | |
| 59 | +// sub-class of UILabel that knows how to change it's state | |
| 60 | +@interface V8HorizontalPickerLabel : UILabel <V8HorizontalPickerElementState> { } | |
| 61 | + | |
| 62 | +@property (nonatomic, assign) BOOL selectedElement; | |
| 63 | +@property (nonatomic, retain) UIColor *selectedStateColor; | |
| 64 | +@property (nonatomic, retain) UIColor *normalStateColor; | |
| 65 | + | |
| 66 | +@end | ... | ... |
LiveVideoCloud/LiveVideoCloud/Classes/SDK/V8HorizontalPickerView/V8HorizontalPickerView.m
0 → 100755
| 1 | +// | |
| 2 | +// V8HorizontalPickerView.m | |
| 3 | +// | |
| 4 | +// Created by Shawn Veader on 9/17/10. | |
| 5 | +// Copyright 2010 V8 Labs, LLC. All rights reserved. | |
| 6 | +// | |
| 7 | + | |
| 8 | +#import "V8HorizontalPickerView.h" | |
| 9 | + | |
| 10 | +#define CurrentBgTag 9999 | |
| 11 | + | |
| 12 | +#pragma mark - Internal Method Interface | |
| 13 | +@interface V8HorizontalPickerView () { | |
| 14 | + UIScrollView *_scrollView; | |
| 15 | + UIView *_currentBg; | |
| 16 | + | |
| 17 | + // collection of widths of each element. | |
| 18 | + NSMutableArray *_elementWidths; | |
| 19 | + | |
| 20 | + // state keepers | |
| 21 | + BOOL dataHasBeenLoaded; | |
| 22 | + BOOL scrollSizeHasBeenSet; | |
| 23 | + | |
| 24 | + // keep track of which elements are visible for tiling | |
| 25 | + int firstVisibleElement; | |
| 26 | + int lastVisibleElement; | |
| 27 | + | |
| 28 | + NSMutableArray *_lineArray; | |
| 29 | + BOOL _reload; | |
| 30 | +} | |
| 31 | + | |
| 32 | +@end | |
| 33 | + | |
| 34 | + | |
| 35 | +#pragma mark - Implementation | |
| 36 | +@implementation V8HorizontalPickerView : UIView | |
| 37 | + | |
| 38 | +@synthesize dataSource, delegate; | |
| 39 | +@synthesize numberOfElements, currentSelectedIndex; // readonly | |
| 40 | +@synthesize elementFont, textColor, selectedTextColor, currentBgImage; | |
| 41 | +@synthesize leftEdgeView, rightEdgeView; | |
| 42 | +@synthesize leftScrollEdgeView, rightScrollEdgeView, scrollEdgeViewPadding,elementPadding; | |
| 43 | + | |
| 44 | +#pragma mark - Init/Dealloc | |
| 45 | +- (id)initWithFrame:(CGRect)frame { | |
| 46 | + if ((self = [super initWithFrame:frame])) { | |
| 47 | + _elementWidths = [[NSMutableArray array] retain]; | |
| 48 | + _lineArray = [[NSMutableArray array] retain]; | |
| 49 | + | |
| 50 | + [self addScrollView]; | |
| 51 | + | |
| 52 | + self.textColor = [UIColor blackColor]; | |
| 53 | + self.elementFont = [UIFont systemFontOfSize:12.0f]; | |
| 54 | + | |
| 55 | + currentSelectedIndex = -1; // nothing is selected yet | |
| 56 | + | |
| 57 | + numberOfElements = 0; | |
| 58 | + elementPadding = 8; | |
| 59 | + dataHasBeenLoaded = NO; | |
| 60 | + scrollSizeHasBeenSet = NO; | |
| 61 | + | |
| 62 | + firstVisibleElement = -1; | |
| 63 | + lastVisibleElement = -1; | |
| 64 | + | |
| 65 | + scrollEdgeViewPadding = 0.0f; | |
| 66 | + | |
| 67 | + self.autoresizesSubviews = YES; | |
| 68 | + _reload = NO; | |
| 69 | + self.clickElementEnable = YES; | |
| 70 | + } | |
| 71 | + return self; | |
| 72 | +} | |
| 73 | + | |
| 74 | +- (id)initWithFrame:(CGRect)frame plugins:(BOOL)plugins myVideos:(BOOL)myVideos | |
| 75 | +{ | |
| 76 | + if ((self = [super initWithFrame:frame])) { | |
| 77 | + _plugins = plugins; | |
| 78 | + _myVideos = myVideos; | |
| 79 | + _elementWidths = [[NSMutableArray array] retain]; | |
| 80 | + _lineArray = [[NSMutableArray array] retain]; | |
| 81 | + | |
| 82 | + [self addScrollView]; | |
| 83 | + | |
| 84 | + self.textColor = [UIColor blackColor]; | |
| 85 | + self.elementFont = [UIFont systemFontOfSize:12.0f]; | |
| 86 | + | |
| 87 | + currentSelectedIndex = -1; // nothing is selected yet | |
| 88 | + | |
| 89 | + numberOfElements = 0; | |
| 90 | + elementPadding = 8; | |
| 91 | + dataHasBeenLoaded = NO; | |
| 92 | + scrollSizeHasBeenSet = NO; | |
| 93 | + | |
| 94 | + firstVisibleElement = -1; | |
| 95 | + lastVisibleElement = -1; | |
| 96 | + | |
| 97 | + scrollEdgeViewPadding = 0.0f; | |
| 98 | + | |
| 99 | + self.autoresizesSubviews = YES; | |
| 100 | + _reload = NO; | |
| 101 | + self.clickElementEnable = YES; | |
| 102 | + } | |
| 103 | + return self; | |
| 104 | +} | |
| 105 | + | |
| 106 | +- (id)initWithFrame:(CGRect)frame home:(BOOL)home | |
| 107 | +{ | |
| 108 | + if ((self = [super initWithFrame:frame])) { | |
| 109 | + | |
| 110 | + _home = home; | |
| 111 | + | |
| 112 | + _elementWidths = [[NSMutableArray array] retain]; | |
| 113 | + _lineArray = [[NSMutableArray array] retain]; | |
| 114 | + | |
| 115 | + [self addScrollView]; | |
| 116 | + | |
| 117 | + self.textColor = [UIColor blackColor]; | |
| 118 | + self.elementFont = [UIFont systemFontOfSize:12.0f]; | |
| 119 | + | |
| 120 | + currentSelectedIndex = -1; // nothing is selected yet | |
| 121 | + | |
| 122 | + numberOfElements = 0; | |
| 123 | + elementPadding = 8; | |
| 124 | + dataHasBeenLoaded = NO; | |
| 125 | + scrollSizeHasBeenSet = NO; | |
| 126 | + | |
| 127 | + firstVisibleElement = -1; | |
| 128 | + lastVisibleElement = -1; | |
| 129 | + | |
| 130 | + scrollEdgeViewPadding = 0.0f; | |
| 131 | + | |
| 132 | + self.autoresizesSubviews = YES; | |
| 133 | + _reload = NO; | |
| 134 | + self.clickElementEnable = YES; | |
| 135 | + } | |
| 136 | + return self; | |
| 137 | +} | |
| 138 | + | |
| 139 | +- (void)dealloc { | |
| 140 | + _scrollView.delegate = nil; | |
| 141 | + | |
| 142 | + [_lineArray release]; | |
| 143 | + [_scrollView release]; | |
| 144 | + [_elementWidths release]; | |
| 145 | + [elementFont release]; | |
| 146 | + [leftEdgeView release]; | |
| 147 | + [rightEdgeView release]; | |
| 148 | + | |
| 149 | + [leftScrollEdgeView release]; | |
| 150 | + [rightScrollEdgeView release]; | |
| 151 | + | |
| 152 | + [textColor release]; | |
| 153 | + [_currentBg release]; | |
| 154 | + [super dealloc]; | |
| 155 | +} | |
| 156 | + | |
| 157 | + | |
| 158 | +#pragma mark - LayoutSubViews | |
| 159 | +- (void)layoutSubviews { | |
| 160 | + [super layoutSubviews]; | |
| 161 | + | |
| 162 | +// if (!(_isChatRoom && [_isChatRoom isEqualToString:@"yes"])) { | |
| 163 | +// if (![self viewWithTag:1110]) { | |
| 164 | +// UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, self.frame.size.height-0.5, self.frame.size.width, 0.5)]; | |
| 165 | +// line.tag = 1110; | |
| 166 | +// [self addSubview:line]; | |
| 167 | +// line.backgroundColor = [Tools colorWithHexString:@"#d5d5d5"]; | |
| 168 | +// [line release]; | |
| 169 | +// } | |
| 170 | +// } | |
| 171 | + | |
| 172 | + BOOL adjustWhenFinished = NO; | |
| 173 | + | |
| 174 | + if (!dataHasBeenLoaded) { | |
| 175 | + [self collectData]; | |
| 176 | + } | |
| 177 | + if (!scrollSizeHasBeenSet) { | |
| 178 | + adjustWhenFinished = YES; | |
| 179 | + [self setTotalWidthOfScrollContent]; | |
| 180 | + } | |
| 181 | + | |
| 182 | + SEL titleForElementSelector = @selector(horizontalPickerView:titleForElementAtIndex:); | |
| 183 | + SEL viewForElementSelector = @selector(horizontalPickerView:viewForElementAtIndex:); | |
| 184 | + SEL setSelectedSelector = @selector(setSelectedElement:); | |
| 185 | + | |
| 186 | + CGRect visibleBounds = [self bounds]; | |
| 187 | + CGRect scaledViewFrame = CGRectZero; | |
| 188 | + | |
| 189 | + // remove any subviews that are no longer visible | |
| 190 | + for (UIView *view in [_scrollView subviews]) { | |
| 191 | + scaledViewFrame = [_scrollView convertRect:[view frame] toView:self]; | |
| 192 | + | |
| 193 | + // if the view doesn't intersect, it's not visible, so we can recycle it | |
| 194 | + if (view.tag!=CurrentBgTag&&!CGRectIntersectsRect(scaledViewFrame, visibleBounds)) { | |
| 195 | + [view removeFromSuperview]; | |
| 196 | + }else { // if it is still visible, update it's selected state | |
| 197 | + if ([view respondsToSelector:setSelectedSelector]) { | |
| 198 | + // view's tag is it's index | |
| 199 | + BOOL isSelected = (currentSelectedIndex == [self indexForElement:view]); | |
| 200 | + // casting to V8HorizontalPickerLabel so we can call this without all the NSInvocation jazz | |
| 201 | + [(V8HorizontalPickerLabel *)view setSelectedElement:isSelected]; | |
| 202 | + } else { | |
| 203 | + for (UIView *view1 in [view subviews]) { | |
| 204 | + if ([view1 respondsToSelector:setSelectedSelector]) { | |
| 205 | + // view's tag is it's index | |
| 206 | + BOOL isSelected = (currentSelectedIndex == view1.tag-100); | |
| 207 | + // casting to V8HorizontalPickerLabel so we can call this without all the NSInvocation jazz | |
| 208 | + [(V8HorizontalPickerLabel *)view1 setSelectedElement:isSelected]; | |
| 209 | + } | |
| 210 | + } | |
| 211 | + } | |
| 212 | + } | |
| 213 | + } | |
| 214 | + | |
| 215 | + // find needed elements by looking at left and right edges of frame | |
| 216 | + CGPoint offset = _scrollView.contentOffset; | |
| 217 | + int firstNeededElement = [self nearestElementToPoint:CGPointMake(offset.x, 0.0f)]; | |
| 218 | + int lastNeededElement = [self nearestElementToPoint:CGPointMake(offset.x + visibleBounds.size.width, 0.0f)]; | |
| 219 | + | |
| 220 | + // add any views that have become visible | |
| 221 | + UIView *view = nil; | |
| 222 | + CGRect tmpViewFrame = CGRectZero; | |
| 223 | + CGPoint itemViewCenter = CGPointZero; | |
| 224 | + for (int i = firstNeededElement; i <= lastNeededElement; i++) { | |
| 225 | + view = nil; // paranoia | |
| 226 | + view = [_scrollView viewWithTag:[self tagForElementAtIndex:i]]; | |
| 227 | + if (!view) { | |
| 228 | + if (i < numberOfElements) { // make sure we are not requesting data out of range | |
| 229 | + if (self.delegate && [self.delegate respondsToSelector:titleForElementSelector]) { | |
| 230 | + NSString *title = [self.delegate horizontalPickerView:self titleForElementAtIndex:i]; | |
| 231 | + view = [self labelForForElementAtIndex:i withTitle:title]; | |
| 232 | + } else if (self.delegate && [self.delegate respondsToSelector:viewForElementSelector]) { | |
| 233 | + view = [self.delegate horizontalPickerView:self viewForElementAtIndex:i]; | |
| 234 | + // move view's center to the center of item's ideal frame | |
| 235 | + tmpViewFrame = [self frameForElementAtIndex:i currentBg:NO]; | |
| 236 | + itemViewCenter = CGPointMake((tmpViewFrame.size.width / 2.0f) + tmpViewFrame.origin.x, (tmpViewFrame.size.height / 2.0f)); | |
| 237 | + view.center = itemViewCenter; | |
| 238 | + } | |
| 239 | + | |
| 240 | + if (view) { | |
| 241 | + // use the index as the tag so we can find it later | |
| 242 | + view.tag = [self tagForElementAtIndex:i]; | |
| 243 | + | |
| 244 | + [_scrollView addSubview:view]; | |
| 245 | + } | |
| 246 | + } | |
| 247 | + } | |
| 248 | + } | |
| 249 | + | |
| 250 | + // add the left or right edge views if visible | |
| 251 | + CGRect viewFrame = CGRectZero; | |
| 252 | + if (leftScrollEdgeView) { | |
| 253 | + viewFrame = [self frameForLeftScrollEdgeView]; | |
| 254 | + scaledViewFrame = [_scrollView convertRect:viewFrame toView:self]; | |
| 255 | + if (CGRectIntersectsRect(scaledViewFrame, visibleBounds) && ![leftScrollEdgeView isDescendantOfView:_scrollView]) { | |
| 256 | + leftScrollEdgeView.frame = viewFrame; | |
| 257 | + [_scrollView addSubview:leftScrollEdgeView]; | |
| 258 | + } | |
| 259 | + } | |
| 260 | + if (rightScrollEdgeView) { | |
| 261 | + viewFrame = [self frameForRightScrollEdgeView]; | |
| 262 | + scaledViewFrame = [_scrollView convertRect:viewFrame toView:self]; | |
| 263 | + if (CGRectIntersectsRect(scaledViewFrame, visibleBounds) && ![rightScrollEdgeView isDescendantOfView:_scrollView]) { | |
| 264 | + rightScrollEdgeView.frame = viewFrame; | |
| 265 | + [_scrollView addSubview:rightScrollEdgeView]; | |
| 266 | + } | |
| 267 | + } | |
| 268 | + | |
| 269 | + // save off what's visible now | |
| 270 | + firstVisibleElement = firstNeededElement; | |
| 271 | + lastVisibleElement = lastNeededElement; | |
| 272 | + | |
| 273 | + // determine if scroll view needs to shift in response to resizing? | |
| 274 | + if (currentSelectedIndex > -1 && adjustWhenFinished) { | |
| 275 | + [self scrollToElement:currentSelectedIndex animated:NO]; | |
| 276 | + } | |
| 277 | + | |
| 278 | + if (_reload) { | |
| 279 | + for (UIView *view in _lineArray) { | |
| 280 | + [view removeFromSuperview]; | |
| 281 | + } | |
| 282 | + [_lineArray removeAllObjects]; | |
| 283 | + } | |
| 284 | + | |
| 285 | +// if (_lineArray.count == 0) { | |
| 286 | +// int x = 0; | |
| 287 | +// int i = 0; | |
| 288 | +// for (NSNumber *number in _elementWidths) { | |
| 289 | +// if (i < _elementWidths.count-1) { | |
| 290 | +// NSInteger width = [number integerValue]; | |
| 291 | +// x += width; | |
| 292 | +// UIView *line = [[UIView alloc] initWithFrame:CGRectMake(x+8*i+3, (self.bounds.size.height-15)/2, 0.5, 15)]; | |
| 293 | +// line.backgroundColor = [Tools colorWithHexString:@"#d5d5d5"]; | |
| 294 | +// if (_isChatRoom && [_isChatRoom isEqualToString:@"yes"]) { | |
| 295 | +// line.backgroundColor = [UIColor whiteColor]; | |
| 296 | +// } | |
| 297 | +// [_lineArray addObject:line]; | |
| 298 | +// [line release]; | |
| 299 | +// } | |
| 300 | +// i++; | |
| 301 | +// } | |
| 302 | +// if (_lineArray.count != 0) { | |
| 303 | +// _reload = NO; | |
| 304 | +// [self setNeedsLayout]; | |
| 305 | +// } | |
| 306 | +// } else { | |
| 307 | +// for (UIView *view in _lineArray) { | |
| 308 | +// if (view.superview == nil) { | |
| 309 | +// [_scrollView addSubview:view]; | |
| 310 | +// } | |
| 311 | +// } | |
| 312 | +// } | |
| 313 | + | |
| 314 | +} | |
| 315 | + | |
| 316 | + | |
| 317 | +#pragma mark - Getters and Setters | |
| 318 | +- (void)setDelegate:(id)newDelegate { | |
| 319 | + if (delegate != newDelegate) { | |
| 320 | + delegate = newDelegate; | |
| 321 | + [self collectData]; | |
| 322 | + } | |
| 323 | +} | |
| 324 | + | |
| 325 | +- (void)setDataSource:(id)newDataSource { | |
| 326 | + if (dataSource != newDataSource) { | |
| 327 | + dataSource = newDataSource; | |
| 328 | + [self collectData]; | |
| 329 | + } | |
| 330 | +} | |
| 331 | + | |
| 332 | +// allow the setting of this views background color to change the scroll view | |
| 333 | +- (void)setBackgroundColor:(UIColor *)newColor { | |
| 334 | + [super setBackgroundColor:newColor]; | |
| 335 | + _scrollView.backgroundColor = newColor; | |
| 336 | + // TODO: set all subviews as well? | |
| 337 | +} | |
| 338 | + | |
| 339 | +- (void)setLeftEdgeView:(UIView *)leftView { | |
| 340 | + if (leftEdgeView != leftView) { | |
| 341 | + if (leftEdgeView) { | |
| 342 | + [leftEdgeView removeFromSuperview]; | |
| 343 | + [leftEdgeView release]; | |
| 344 | + } | |
| 345 | + leftEdgeView = [leftView retain]; | |
| 346 | + | |
| 347 | + CGRect tmpFrame = leftEdgeView.frame; | |
| 348 | + tmpFrame.origin.x = 0.0f; | |
| 349 | + tmpFrame.origin.y = 0.0f; | |
| 350 | + leftEdgeView.frame = tmpFrame; | |
| 351 | + [self addSubview:leftEdgeView]; | |
| 352 | + } | |
| 353 | +} | |
| 354 | + | |
| 355 | +- (void)setRightEdgeView:(UIView *)rightView { | |
| 356 | + if (rightEdgeView != rightView) { | |
| 357 | + if (rightEdgeView) { | |
| 358 | + [rightEdgeView removeFromSuperview]; | |
| 359 | + [rightEdgeView release]; | |
| 360 | + } | |
| 361 | + rightEdgeView = [rightView retain]; | |
| 362 | + | |
| 363 | + CGRect tmpFrame = rightEdgeView.frame; | |
| 364 | + tmpFrame.origin.x = self.frame.size.width - tmpFrame.size.width; | |
| 365 | + tmpFrame.origin.y = 0.0f; | |
| 366 | + rightEdgeView.frame = tmpFrame; | |
| 367 | + [self addSubview:rightEdgeView]; | |
| 368 | + } | |
| 369 | +} | |
| 370 | + | |
| 371 | +- (void)setLeftScrollEdgeView:(UIView *)leftView { | |
| 372 | + if (leftScrollEdgeView != leftView) { | |
| 373 | + if (leftScrollEdgeView) { | |
| 374 | + [leftScrollEdgeView removeFromSuperview]; | |
| 375 | + [leftScrollEdgeView release]; | |
| 376 | + } | |
| 377 | + leftScrollEdgeView = [leftView retain]; | |
| 378 | + | |
| 379 | + scrollSizeHasBeenSet = NO; | |
| 380 | + [self setNeedsLayout]; | |
| 381 | + } | |
| 382 | +} | |
| 383 | + | |
| 384 | +- (void)setRightScrollEdgeView:(UIView *)rightView { | |
| 385 | + if (rightScrollEdgeView != rightView) { | |
| 386 | + if (rightScrollEdgeView) { | |
| 387 | + [rightScrollEdgeView removeFromSuperview]; | |
| 388 | + [rightScrollEdgeView release]; | |
| 389 | + } | |
| 390 | + rightScrollEdgeView = [rightView retain]; | |
| 391 | + | |
| 392 | + scrollSizeHasBeenSet = NO; | |
| 393 | + [self setNeedsLayout]; | |
| 394 | + } | |
| 395 | +} | |
| 396 | + | |
| 397 | +- (void)setFrame:(CGRect)newFrame { | |
| 398 | + if (!CGRectEqualToRect(self.frame, newFrame)) { | |
| 399 | + // causes recalulation of offsets, etc based on new size | |
| 400 | + scrollSizeHasBeenSet = NO; | |
| 401 | + } | |
| 402 | + [super setFrame:newFrame]; | |
| 403 | +} | |
| 404 | + | |
| 405 | +- (void)setCurrentBgImage:(UIImage *)bgImage{ | |
| 406 | + if (currentBgImage != bgImage) { | |
| 407 | + if (currentBgImage) { | |
| 408 | + [currentBgImage release]; | |
| 409 | + } | |
| 410 | + currentBgImage = [bgImage retain]; | |
| 411 | + | |
| 412 | + if (_currentBg) { | |
| 413 | + if (_isChatRoom && [_isChatRoom isEqualToString:@"yes"]) { | |
| 414 | + | |
| 415 | + CGFloat y = self.plugins ? (self.bounds.size.height-27)/2 : self.height - 1; | |
| 416 | + CGFloat height = self.plugins ? 27 : 1; | |
| 417 | + _currentBg.frame = CGRectMake(0, y, 0, height); | |
| 418 | + _currentBg.backgroundColor = [UIColor whiteColor]; | |
| 419 | + } | |
| 420 | + } | |
| 421 | + } | |
| 422 | +} | |
| 423 | + | |
| 424 | +#pragma mark - Data Fetching Methods | |
| 425 | +- (void)reloadData { | |
| 426 | + // remove all scrollview subviews and "recycle" them | |
| 427 | + for (UIView *view in [_scrollView subviews]) { | |
| 428 | + if (view.tag==CurrentBgTag) { | |
| 429 | + view.frame = CGRectZero; | |
| 430 | + continue; | |
| 431 | + } | |
| 432 | + [view removeFromSuperview]; | |
| 433 | + } | |
| 434 | + _reload = YES; | |
| 435 | + firstVisibleElement = NSIntegerMax; | |
| 436 | + lastVisibleElement = NSIntegerMin; | |
| 437 | + | |
| 438 | + [self collectData]; | |
| 439 | +} | |
| 440 | + | |
| 441 | +- (void)collectData { | |
| 442 | + scrollSizeHasBeenSet = NO; | |
| 443 | + dataHasBeenLoaded = NO; | |
| 444 | + | |
| 445 | + [self getNumberOfElementsFromDataSource]; | |
| 446 | + [self getElementWidthsFromDelegate]; | |
| 447 | + [self setTotalWidthOfScrollContent]; | |
| 448 | + | |
| 449 | + dataHasBeenLoaded = YES; | |
| 450 | + [self setNeedsLayout]; | |
| 451 | + | |
| 452 | + [self scrollToElement:currentSelectedIndex animated:NO]; | |
| 453 | +} | |
| 454 | + | |
| 455 | + | |
| 456 | +#pragma mark - Scroll To Element Method | |
| 457 | +- (void)scrollToElement:(NSInteger)index animated:(BOOL)animate { | |
| 458 | + if (numberOfElements < 1) { | |
| 459 | + return ; | |
| 460 | + }else if (index<0) { | |
| 461 | + index = 0; | |
| 462 | + }else if (index>numberOfElements-1) { | |
| 463 | + index = numberOfElements-1; | |
| 464 | + } | |
| 465 | + | |
| 466 | + currentSelectedIndex = index; | |
| 467 | + | |
| 468 | + [UIView beginAnimations:nil context:nil]; | |
| 469 | + _currentBg.frame = [self frameForElementAtIndex:index currentBg:YES]; | |
| 470 | + if (self.plugins) { | |
| 471 | + _currentBg.frame = CGRectMake(_currentBg.frame.origin.x+(_currentBg.bounds.size.width-100)/2, (self.bounds.size.height-28)/2, 100, 28); | |
| 472 | + } | |
| 473 | +// _selectLine.frame = CGRectMake([self frameForElementAtIndex:index].origin.x, 35, [self frameForElementAtIndex:index].size.width, 2); | |
| 474 | + [UIView commitAnimations]; | |
| 475 | + | |
| 476 | + int offsetX = [self offsetForElementAtIndex:index]; | |
| 477 | + int width = [self widthOfElementAtIndex:index]; | |
| 478 | + | |
| 479 | + if (offsetX < _scrollView.contentOffset.x) { | |
| 480 | + [_scrollView setContentOffset:CGPointMake(offsetX, 0) animated:animate]; | |
| 481 | + }else if((offsetX+width) > (_scrollView.contentOffset.x+self.bounds.size.width)){ | |
| 482 | + [_scrollView setContentOffset:CGPointMake((offsetX+width-self.bounds.size.width), 0) animated:animate]; | |
| 483 | + } | |
| 484 | + | |
| 485 | + // notify delegate of the selected index | |
| 486 | + SEL delegateCall = @selector(horizontalPickerView:didSelectElementAtIndex:); | |
| 487 | + if (self.delegate && [self.delegate respondsToSelector:delegateCall]) { | |
| 488 | + [self.delegate horizontalPickerView:self didSelectElementAtIndex:index]; | |
| 489 | + } | |
| 490 | + | |
| 491 | +#if (__IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_4_3) | |
| 492 | + [self setNeedsLayout]; | |
| 493 | +#endif | |
| 494 | +} | |
| 495 | + | |
| 496 | +#pragma mark - UIScrollViewDelegate Methods | |
| 497 | +- (void)scrollViewDidScroll:(UIScrollView *)scrollView { | |
| 498 | +#if (__IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_4_3) | |
| 499 | + [self setNeedsLayout]; | |
| 500 | +#endif | |
| 501 | +} | |
| 502 | + | |
| 503 | +#pragma mark - View Creation Methods (Internal Methods) | |
| 504 | +- (void)addScrollView { | |
| 505 | + if (_scrollView == nil) { | |
| 506 | + _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; | |
| 507 | + _scrollView.delegate = self; | |
| 508 | + _scrollView.scrollEnabled = YES; | |
| 509 | + _scrollView.scrollsToTop = NO; | |
| 510 | + _scrollView.showsVerticalScrollIndicator = NO; | |
| 511 | + _scrollView.showsHorizontalScrollIndicator = NO; | |
| 512 | + _scrollView.bouncesZoom = NO; | |
| 513 | + _scrollView.alwaysBounceHorizontal = YES; | |
| 514 | + _scrollView.alwaysBounceVertical = NO; | |
| 515 | + _scrollView.minimumZoomScale = 1.0; // setting min/max the same disables zooming | |
| 516 | + _scrollView.maximumZoomScale = 1.0; | |
| 517 | + _scrollView.contentInset = UIEdgeInsetsZero; | |
| 518 | + _scrollView.decelerationRate = 0.1; //UIScrollViewDecelerationRateNormal; | |
| 519 | + _scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; | |
| 520 | + _scrollView.autoresizesSubviews = YES; | |
| 521 | + | |
| 522 | + UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewTapped:)]; | |
| 523 | + [_scrollView addGestureRecognizer:tapRecognizer]; | |
| 524 | + [tapRecognizer release]; | |
| 525 | + | |
| 526 | + /* | |
| 527 | + //V8下面的细线 | |
| 528 | + if (self.plugins || self.myVideos || self.home) { | |
| 529 | + | |
| 530 | + CGFloat y = self.plugins ? (self.bounds.size.height-27)/2 : self.height - 1; | |
| 531 | + CGFloat height = self.plugins ? 27 : 1; | |
| 532 | + | |
| 533 | + _currentBg = [[UIImageView alloc]init]; | |
| 534 | + _currentBg = [[UIView alloc] initWithFrame:CGRectMake(0, y, 0, height)]; | |
| 535 | + _currentBg.tag = CurrentBgTag; | |
| 536 | + _currentBg.backgroundColor = self.plugins ? [UIColor colorWithHexString:@"#fff100"] : [UIColor whiteColor]; | |
| 537 | + _currentBg.layer.borderColor = [UIColor colorWithHexString:@"#f6e80e"].CGColor; | |
| 538 | + _currentBg.layer.borderWidth = 0.5; | |
| 539 | + | |
| 540 | + if (self.plugins) { | |
| 541 | + _currentBg.layer.cornerRadius = 13.5; | |
| 542 | + _currentBg.layer.masksToBounds = YES; | |
| 543 | + | |
| 544 | + } | |
| 545 | + [_scrollView addSubview:_currentBg]; | |
| 546 | + } | |
| 547 | + */ | |
| 548 | + | |
| 549 | + [self addSubview:_scrollView]; | |
| 550 | + | |
| 551 | + } | |
| 552 | +} | |
| 553 | + | |
| 554 | +// create a UILabel for this element. | |
| 555 | +- (V8HorizontalPickerLabel *)labelForForElementAtIndex:(NSInteger)index withTitle:(NSString *)title { | |
| 556 | + CGRect labelFrame = [self frameForElementAtIndex:index currentBg:NO]; | |
| 557 | + V8HorizontalPickerLabel *elementLabel = [[V8HorizontalPickerLabel alloc] initWithFrame:labelFrame]; | |
| 558 | + | |
| 559 | + elementLabel.textAlignment = NSTextAlignmentCenter; | |
| 560 | + elementLabel.backgroundColor = [UIColor clearColor]; | |
| 561 | + elementLabel.text = title; | |
| 562 | + elementLabel.font = self.elementFont; | |
| 563 | + | |
| 564 | + elementLabel.normalStateColor = self.textColor; | |
| 565 | + elementLabel.selectedStateColor = self.selectedTextColor; | |
| 566 | + | |
| 567 | + elementLabel.selectedElement = (currentSelectedIndex == index); | |
| 568 | + | |
| 569 | + return [elementLabel autorelease]; | |
| 570 | +} | |
| 571 | + | |
| 572 | + | |
| 573 | +#pragma mark - DataSource Calling Method (Internal Method) | |
| 574 | +- (void)getNumberOfElementsFromDataSource { | |
| 575 | + SEL dataSourceCall = @selector(numberOfElementsInHorizontalPickerView:); | |
| 576 | + if (self.dataSource && [self.dataSource respondsToSelector:dataSourceCall]) { | |
| 577 | + numberOfElements = [self.dataSource numberOfElementsInHorizontalPickerView:self]; | |
| 578 | + } else { | |
| 579 | + numberOfElements = 0; | |
| 580 | + } | |
| 581 | +} | |
| 582 | + | |
| 583 | + | |
| 584 | +#pragma mark - Delegate Calling Method (Internal Method) | |
| 585 | +- (void)getElementWidthsFromDelegate { | |
| 586 | + SEL delegateCall = @selector(horizontalPickerView:widthForElementAtIndex:); | |
| 587 | + [_elementWidths removeAllObjects]; | |
| 588 | + for (int i = 0; i < numberOfElements; i++) { | |
| 589 | + if (self.delegate && [self.delegate respondsToSelector:delegateCall]) { | |
| 590 | + NSInteger width = [self.delegate horizontalPickerView:self widthForElementAtIndex:i]; | |
| 591 | + [_elementWidths addObject:[NSNumber numberWithInteger:width]]; | |
| 592 | + } | |
| 593 | + } | |
| 594 | + | |
| 595 | +// int x = 0; | |
| 596 | +// for (NSNumber *number in _elementWidths) { | |
| 597 | +// NSInteger width = [number integerValue]; | |
| 598 | +// x += width; | |
| 599 | +// UIView *line = [[UIView alloc] initWithFrame:CGRectMake(x, 11, 1, 15)]; | |
| 600 | +// [_scrollView addSubview:line]; | |
| 601 | +//// line.backgroundColor = [Utility colorWithHexString:@"#d5d5d5"]; | |
| 602 | +// line.backgroundColor = [UIColor redColor]; | |
| 603 | +// [line release]; | |
| 604 | +// } | |
| 605 | + | |
| 606 | +} | |
| 607 | + | |
| 608 | + | |
| 609 | +#pragma mark - View Calculation and Manipulation Methods (Internal Methods) | |
| 610 | +// what is the total width of the content area? | |
| 611 | +- (void)setTotalWidthOfScrollContent { | |
| 612 | + NSInteger totalWidth = 0; | |
| 613 | + | |
| 614 | + totalWidth += [self leftScrollEdgeWidth]; | |
| 615 | + totalWidth += [self rightScrollEdgeWidth]; | |
| 616 | + | |
| 617 | + // sum the width of all elements | |
| 618 | + for (NSNumber *width in _elementWidths) { | |
| 619 | + totalWidth += [width intValue]; | |
| 620 | + totalWidth += elementPadding; | |
| 621 | + } | |
| 622 | + // TODO: is this necessary? | |
| 623 | + totalWidth -= elementPadding; // we add "one too many" in for loop | |
| 624 | + | |
| 625 | + if (_scrollView) { | |
| 626 | + // create our scroll view as wide as all the elements to be included | |
| 627 | + _scrollView.contentSize = CGSizeMake(totalWidth, self.bounds.size.height); | |
| 628 | + scrollSizeHasBeenSet = YES; | |
| 629 | + } | |
| 630 | +} | |
| 631 | + | |
| 632 | +// what is the left-most edge of the element at the given index? | |
| 633 | +- (NSInteger)offsetForElementAtIndex:(NSInteger)index { | |
| 634 | + NSInteger offset = 0; | |
| 635 | + if (index >= [_elementWidths count]) { | |
| 636 | + return 0; | |
| 637 | + } | |
| 638 | + | |
| 639 | + offset += [self leftScrollEdgeWidth]; | |
| 640 | + | |
| 641 | + for (int i = 0; i < index && i < [_elementWidths count]; i++) { | |
| 642 | + offset += [[_elementWidths safetyObjectAtIndex:i] intValue]; | |
| 643 | + offset += elementPadding; | |
| 644 | + } | |
| 645 | + return offset; | |
| 646 | +} | |
| 647 | + | |
| 648 | +// return the tag for an element at a given index | |
| 649 | +- (NSInteger)tagForElementAtIndex:(NSInteger)index { | |
| 650 | + return (index + 1) * 10; | |
| 651 | +} | |
| 652 | + | |
| 653 | +// return the index given an element's tag | |
| 654 | +- (NSInteger)indexForElement:(UIView *)element { | |
| 655 | + return (element.tag / 10) - 1; | |
| 656 | +} | |
| 657 | + | |
| 658 | +// what is the width of the element at the given index? | |
| 659 | +- (NSInteger)widthOfElementAtIndex:(NSInteger)index { | |
| 660 | + return [[_elementWidths safetyObjectAtIndex:index] intValue]; | |
| 661 | +} | |
| 662 | + | |
| 663 | +// what is the frame for the element at the given index? | |
| 664 | +- (CGRect)frameForElementAtIndex:(NSInteger)index currentBg:(BOOL)flag { | |
| 665 | + CGFloat width = 0.0f; | |
| 666 | + if ([_elementWidths count] > index) { | |
| 667 | + width = [[_elementWidths safetyObjectAtIndex:index] intValue]; | |
| 668 | + } | |
| 669 | + if (flag) { | |
| 670 | + if (_isChatRoom && [_isChatRoom isEqualToString:@"yes"]) { | |
| 671 | + return CGRectMake([self offsetForElementAtIndex:index]-5, self.bounds.size.height-28, width+8.5, 28); | |
| 672 | + } | |
| 673 | + CGFloat y = self.plugins ? (self.bounds.size.height-27)/2 : self.height -1; | |
| 674 | + CGFloat height = self.plugins ? 27 : 1; | |
| 675 | + if (self.home) { | |
| 676 | + return CGRectMake([self offsetForElementAtIndex:index]+8, y, width-16, height); | |
| 677 | + } | |
| 678 | + return CGRectMake([self offsetForElementAtIndex:index], y, width, height); | |
| 679 | + } else { | |
| 680 | + return CGRectMake([self offsetForElementAtIndex:index], 0.0f, width, self.frame.size.height); | |
| 681 | + } | |
| 682 | +} | |
| 683 | + | |
| 684 | +// what is the frame for the left scroll edge view? | |
| 685 | +- (CGRect)frameForLeftScrollEdgeView { | |
| 686 | + if (leftScrollEdgeView) { | |
| 687 | + CGFloat scrollHeight = _scrollView.contentSize.height; | |
| 688 | + CGFloat viewHeight = leftScrollEdgeView.frame.size.height; | |
| 689 | + return CGRectMake(0.0f, ((scrollHeight / 2.0f) - (viewHeight / 2.0f)), | |
| 690 | + leftScrollEdgeView.frame.size.width, viewHeight); | |
| 691 | + } else { | |
| 692 | + return CGRectZero; | |
| 693 | + } | |
| 694 | +} | |
| 695 | + | |
| 696 | +// what is the width of the left edge of the scroll area? | |
| 697 | +- (CGFloat)leftScrollEdgeWidth { | |
| 698 | + if (leftScrollEdgeView) { | |
| 699 | + CGFloat width = leftScrollEdgeView.frame.size.width; | |
| 700 | + width += scrollEdgeViewPadding; | |
| 701 | + return width; | |
| 702 | + } | |
| 703 | + return 0.0f; | |
| 704 | +} | |
| 705 | + | |
| 706 | +// what is the frame for the right scroll edge view? | |
| 707 | +- (CGRect)frameForRightScrollEdgeView { | |
| 708 | + if (rightScrollEdgeView) { | |
| 709 | + CGFloat scrollWidth = _scrollView.contentSize.width; | |
| 710 | + CGFloat scrollHeight = _scrollView.contentSize.height; | |
| 711 | + CGFloat viewWidth = rightScrollEdgeView.frame.size.width; | |
| 712 | + CGFloat viewHeight = rightScrollEdgeView.frame.size.height; | |
| 713 | + return CGRectMake(scrollWidth - viewWidth, ((scrollHeight / 2.0f) - (viewHeight / 2.0f)), | |
| 714 | + viewWidth, viewHeight); | |
| 715 | + } else { | |
| 716 | + return CGRectZero; | |
| 717 | + } | |
| 718 | +} | |
| 719 | + | |
| 720 | +// what is the width of the right edge of the scroll area? | |
| 721 | +- (CGFloat)rightScrollEdgeWidth { | |
| 722 | + if (rightScrollEdgeView) { | |
| 723 | + CGFloat width = rightScrollEdgeView.frame.size.width; | |
| 724 | + width += scrollEdgeViewPadding; | |
| 725 | + return width; | |
| 726 | + } | |
| 727 | + return 0.0f; | |
| 728 | +} | |
| 729 | + | |
| 730 | +// what is the element nearest to the given point? | |
| 731 | +- (NSInteger)nearestElementToPoint:(CGPoint)point { | |
| 732 | + for (int i = 0; i < numberOfElements; i++) { | |
| 733 | + CGRect frame = [self frameForElementAtIndex:i currentBg:NO]; | |
| 734 | + if (CGRectContainsPoint(frame, point)) { | |
| 735 | + return i; | |
| 736 | + } else if (point.x < frame.origin.x) { | |
| 737 | + // if the center is before this element, go back to last one, | |
| 738 | + // unless we're at the beginning | |
| 739 | + if (i > 0) { | |
| 740 | + return i - 1; | |
| 741 | + } else { | |
| 742 | + return 0; | |
| 743 | + } | |
| 744 | + break; | |
| 745 | + } else if (point.x > frame.origin.y) { | |
| 746 | + // if the center is past the last element, scroll to it | |
| 747 | + if (i == numberOfElements - 1) { | |
| 748 | + return i; | |
| 749 | + } | |
| 750 | + } | |
| 751 | + } | |
| 752 | + return 0; | |
| 753 | +} | |
| 754 | + | |
| 755 | +// similar to nearestElementToPoint: however, this method does not look past beginning/end | |
| 756 | +- (NSInteger)elementContainingPoint:(CGPoint)point { | |
| 757 | + for (int i = 0; i < numberOfElements; i++) { | |
| 758 | + CGRect frame = [self frameForElementAtIndex:i currentBg:NO]; | |
| 759 | + if (CGRectContainsPoint(frame, point)) { | |
| 760 | + return i; | |
| 761 | + } | |
| 762 | + } | |
| 763 | + return -1; | |
| 764 | +} | |
| 765 | + | |
| 766 | +#pragma mark - Tap Gesture Recognizer Handler Method | |
| 767 | +// use the gesture recognizer to slide to element under tap | |
| 768 | +- (void)scrollViewTapped:(UITapGestureRecognizer *)recognizer { | |
| 769 | + if (!self.clickElementEnable) { | |
| 770 | + return; | |
| 771 | + } | |
| 772 | + if (recognizer.state == UIGestureRecognizerStateRecognized) { | |
| 773 | + CGPoint tapLocation = [recognizer locationInView:_scrollView]; | |
| 774 | + NSInteger elementIndex = [self elementContainingPoint:tapLocation]; | |
| 775 | + if (elementIndex != -1) { // point not in element | |
| 776 | + [self scrollToElement:elementIndex animated:YES]; | |
| 777 | + } | |
| 778 | + } | |
| 779 | +} | |
| 780 | + | |
| 781 | +@end | |
| 782 | + | |
| 783 | +// ------------------------------------------------------------------------ | |
| 784 | +#pragma mark - Picker Label Implementation | |
| 785 | +@implementation V8HorizontalPickerLabel : UILabel | |
| 786 | + | |
| 787 | +@synthesize selectedElement, selectedStateColor, normalStateColor; | |
| 788 | + | |
| 789 | +- (void)setSelectedElement:(BOOL)selected { | |
| 790 | + if (selectedElement != selected) { | |
| 791 | + if (selected) { | |
| 792 | + self.textColor = self.selectedStateColor; | |
| 793 | + } else { | |
| 794 | + self.textColor = self.normalStateColor; | |
| 795 | + } | |
| 796 | + selectedElement = selected; | |
| 797 | + [self setNeedsLayout]; | |
| 798 | + } | |
| 799 | +} | |
| 800 | + | |
| 801 | +- (void)setNormalStateColor:(UIColor *)color { | |
| 802 | + if (normalStateColor != color) { | |
| 803 | + [normalStateColor release]; | |
| 804 | + normalStateColor = [color retain]; | |
| 805 | + self.textColor = normalStateColor; | |
| 806 | + [self setNeedsLayout]; | |
| 807 | + } | |
| 808 | +} | |
| 809 | + | |
| 810 | +@end | ... | ... |
LiveVideoCloud/LiveVideoCloud/Classes/SDK/V8HorizontalPickerView/V8HorizontalPickerViewProtocol.h
0 → 100755
| 1 | +// | |
| 2 | +// V8HorizontalPickerViewProtocol.h | |
| 3 | +// | |
| 4 | +// Created by Shawn Veader on 9/17/10. | |
| 5 | +// Copyright 2010 V8 Labs, LLC. All rights reserved. | |
| 6 | +// | |
| 7 | + | |
| 8 | +@class V8HorizontalPickerView; | |
| 9 | + | |
| 10 | +// ------------------------------------------------------------------ | |
| 11 | +// V8HorizontalPickerView DataSource Protocol | |
| 12 | +@protocol V8HorizontalPickerViewDataSource <NSObject> | |
| 13 | +@required | |
| 14 | +// data source is responsible for reporting how many elements there are | |
| 15 | +- (NSInteger)numberOfElementsInHorizontalPickerView:(V8HorizontalPickerView *)picker; | |
| 16 | +@end | |
| 17 | + | |
| 18 | + | |
| 19 | +// ------------------------------------------------------------------ | |
| 20 | +// V8HorizontalPickerView Delegate Protocol | |
| 21 | +@protocol V8HorizontalPickerViewDelegate <NSObject> | |
| 22 | + | |
| 23 | +@optional | |
| 24 | +// delegate callback to notify delegate selected element has changed | |
| 25 | +- (void)horizontalPickerView:(V8HorizontalPickerView *)picker didSelectElementAtIndex:(NSInteger)index; | |
| 26 | + | |
| 27 | +// one of these two methods must be defined | |
| 28 | +- (NSString *)horizontalPickerView:(V8HorizontalPickerView *)picker titleForElementAtIndex:(NSInteger)index; | |
| 29 | +- (UIView *)horizontalPickerView:(V8HorizontalPickerView *)picker viewForElementAtIndex:(NSInteger)index; | |
| 30 | +// any view returned from this must confirm to the V8HorizontalPickerElementState protocol | |
| 31 | + | |
| 32 | +@required | |
| 33 | +// delegate is responsible for reporting the size of each element | |
| 34 | +- (NSInteger)horizontalPickerView:(V8HorizontalPickerView *)picker widthForElementAtIndex:(NSInteger)index; | |
| 35 | + | |
| 36 | +@end | |
| 37 | + | |
| 38 | +// ------------------------------------------------------------------ | |
| 39 | +// V8HorizontalPickerElementState Protocol | |
| 40 | +@protocol V8HorizontalPickerElementState <NSObject> | |
| 41 | +@required | |
| 42 | +// element views should know how display themselves based on selected status | |
| 43 | +- (void)setSelectedElement:(BOOL)selected; | |
| 44 | +@end | |
| 0 | 45 | \ No newline at end of file | ... | ... |
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/Controller/HomeViewController.m
| ... | ... | @@ -12,8 +12,19 @@ |
| 12 | 12 | #import "LVCUGCLivePlayerController.h" |
| 13 | 13 | #import "LVCTVLiveViewController.h" |
| 14 | 14 | #import "LVCUGCLiveListController.h" |
| 15 | +#import "V8HorizontalPickerView.h" | |
| 16 | +#import "MHPagingScrollView.h" | |
| 17 | +#import "LVCTelevisionView.h" | |
| 15 | 18 | |
| 16 | -@interface HomeViewController () | |
| 19 | +@interface HomeViewController ()<V8HorizontalPickerViewDataSource, V8HorizontalPickerViewDelegate,MHPagingScrollViewDelegate,UIScrollViewDelegate> | |
| 20 | +{ | |
| 21 | + NSArray *_titleArr; | |
| 22 | + CGFloat _titleSpace; | |
| 23 | + | |
| 24 | +} | |
| 25 | + | |
| 26 | +@property (nonatomic, strong)V8HorizontalPickerView *titleView; | |
| 27 | +@property (nonatomic, strong)MHPagingScrollView *pageView; | |
| 17 | 28 | |
| 18 | 29 | @end |
| 19 | 30 | |
| ... | ... | @@ -22,7 +33,7 @@ |
| 22 | 33 | - (void)viewDidLoad { |
| 23 | 34 | [super viewDidLoad]; |
| 24 | 35 | // Do any additional setup after loading the view. |
| 25 | - self.view.backgroundColor = [UIColor redColor]; | |
| 36 | + self.view.backgroundColor = [UIColor whiteColor]; | |
| 26 | 37 | self.navigationItem.title = @"首页"; |
| 27 | 38 | |
| 28 | 39 | UIButton *liveBtn = [UIButton buttonWithType:UIButtonTypeCustom]; |
| ... | ... | @@ -42,6 +53,26 @@ |
| 42 | 53 | [UGCLiveListBtn setTitle:@"UGC直播列表" forState:UIControlStateNormal]; |
| 43 | 54 | [UGCLiveListBtn addTarget:self action:@selector(UGCLiveListAction) forControlEvents:UIControlEventTouchUpInside]; |
| 44 | 55 | [self.view addSubview:UGCLiveListBtn]; |
| 56 | + | |
| 57 | + _titleArr = @[@"推荐",@"频道"]; | |
| 58 | + CGFloat width = 0; | |
| 59 | + for (NSString *title in _titleArr) { | |
| 60 | + CGSize size = [title sizeWithAttributes:@{NSFontAttributeName:self.titleView.elementFont}]; | |
| 61 | + width += size.width+5; | |
| 62 | + } | |
| 63 | + if (width < self.titleView.width) { | |
| 64 | + _titleSpace = (self.titleView.width-width)/_titleArr.count; | |
| 65 | + } else { | |
| 66 | + _titleSpace = 0; | |
| 67 | + } | |
| 68 | + | |
| 69 | + self.navigationItem.titleView = self.titleView; | |
| 70 | + | |
| 71 | + [self.view addSubview:self.pageView]; | |
| 72 | + [_pageView reloadPages]; | |
| 73 | + [_titleView reloadData]; | |
| 74 | + [self.titleView scrollToElement:1 animated:NO]; | |
| 75 | + | |
| 45 | 76 | } |
| 46 | 77 | |
| 47 | 78 | - (void)liveAction |
| ... | ... | @@ -63,6 +94,111 @@ |
| 63 | 94 | [self.navigationController pushViewController:listVC animated:YES]; |
| 64 | 95 | } |
| 65 | 96 | |
| 97 | +#pragma mark - V8HorizontalPickerViewDataSource | |
| 98 | + | |
| 99 | +- (NSInteger)numberOfElementsInHorizontalPickerView:(V8HorizontalPickerView *)picker | |
| 100 | +{ | |
| 101 | + return _titleArr.count; | |
| 102 | +} | |
| 103 | + | |
| 104 | +#pragma mark - V8HorizontalPickerViewDelegate | |
| 105 | + | |
| 106 | +- (NSString *)horizontalPickerView:(V8HorizontalPickerView *)picker titleForElementAtIndex:(NSInteger)index | |
| 107 | +{ | |
| 108 | + return _titleArr[index]; | |
| 109 | +} | |
| 110 | + | |
| 111 | +- (NSInteger)horizontalPickerView:(V8HorizontalPickerView *)picker widthForElementAtIndex:(NSInteger)index | |
| 112 | +{ | |
| 113 | + | |
| 114 | + if (_titleSpace != 0) { | |
| 115 | + | |
| 116 | + CGSize size = [_titleArr[index] sizeWithAttributes:@{NSFontAttributeName:self.titleView.elementFont}]; | |
| 117 | + return size.width +_titleSpace; | |
| 118 | + } else { | |
| 119 | + | |
| 120 | + CGSize size = [_titleArr[index] sizeWithAttributes:@{NSFontAttributeName:self.titleView.elementFont}]; | |
| 121 | + return size.width + 15; | |
| 122 | + } | |
| 123 | +} | |
| 124 | + | |
| 125 | +- (void)horizontalPickerView:(V8HorizontalPickerView *)picker didSelectElementAtIndex:(NSInteger)index | |
| 126 | +{ | |
| 127 | + if (self.pageView.indexOfSelectedPage != index) { | |
| 128 | + [self.pageView selectPageAtIndex:index animated:YES]; | |
| 129 | + } | |
| 130 | +} | |
| 131 | + | |
| 132 | +#pragma mark - UIScrollViewDelegate | |
| 133 | + | |
| 134 | +- (void)scrollViewDidScroll:(UIScrollView *)scrollView | |
| 135 | +{ | |
| 136 | + | |
| 137 | + if (self.titleView.currentSelectedIndex != self.pageView.indexOfSelectedPage) { | |
| 138 | + | |
| 139 | + [self.titleView scrollToElement:self.pageView.indexOfSelectedPage animated:YES]; | |
| 140 | + | |
| 141 | + } | |
| 142 | + [self.pageView scrollViewDidScroll]; | |
| 143 | + | |
| 144 | +} | |
| 145 | + | |
| 146 | +#pragma mark - MHPagingScrollViewDelegate | |
| 147 | + | |
| 148 | +- (NSUInteger)numberOfPagesInPagingScrollView:(MHPagingScrollView *)pagingScrollView | |
| 149 | +{ | |
| 150 | + return _titleArr.count; | |
| 151 | +} | |
| 152 | + | |
| 153 | +- (UIView *)pagingScrollView:(MHPagingScrollView *)pagingScrollView pageForIndex:(NSUInteger)index | |
| 154 | +{ | |
| 155 | + if ([_titleArr[index] isEqualToString:@"推荐"]) { | |
| 156 | + | |
| 157 | + LVCTelevisionView *tvView = (LVCTelevisionView *)[pagingScrollView pageViewByIndex:index]; | |
| 158 | + if (!tvView) { | |
| 159 | + tvView = [[LVCTelevisionView alloc] init]; | |
| 160 | + } | |
| 161 | + return tvView; | |
| 162 | + | |
| 163 | + }else if ([_titleArr[index] isEqualToString:@"频道"]) { | |
| 164 | + | |
| 165 | + LVCTelevisionView *tvView = (LVCTelevisionView *)[pagingScrollView pageViewByIndex:index]; | |
| 166 | + if (!tvView) { | |
| 167 | + tvView = [[LVCTelevisionView alloc] init]; | |
| 168 | + } | |
| 169 | + return tvView; | |
| 170 | + } | |
| 171 | + return nil; | |
| 172 | +} | |
| 173 | + | |
| 174 | +- (V8HorizontalPickerView *)titleView | |
| 175 | +{ | |
| 176 | + if (!_titleView) { | |
| 177 | + | |
| 178 | + _titleView = [[V8HorizontalPickerView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH-120, 44) home:YES]; | |
| 179 | + _titleView.textColor = [UIColor colorWithHexString:@"#7e7e7d"]; | |
| 180 | + _titleView.selectedTextColor = [UIColor blackColorZX]; | |
| 181 | + _titleView.delegate = self; | |
| 182 | + _titleView.dataSource = self; | |
| 183 | + _titleView.elementFont = [UIFont boldSystemFontOfSize:18]; | |
| 184 | + _titleView.scrollView.scrollsToTop = NO; | |
| 185 | + | |
| 186 | + } | |
| 187 | + return _titleView; | |
| 188 | +} | |
| 189 | + | |
| 190 | +- (MHPagingScrollView *)pageView | |
| 191 | +{ | |
| 192 | + if (!_pageView) { | |
| 193 | + _pageView = [[MHPagingScrollView alloc] initWithFrame:CGRectMake(0, 64, SCREEN_WIDTH, SCREEN_HEIGHT-64-49)]; | |
| 194 | + _pageView.pagingDelegate = self; | |
| 195 | + _pageView.delegate = self; | |
| 196 | + _pageView.scrollsToTop = NO; | |
| 197 | + _pageView.bounces = NO; | |
| 198 | + } | |
| 199 | + return _pageView; | |
| 200 | +} | |
| 201 | + | |
| 66 | 202 | - (void)didReceiveMemoryWarning { |
| 67 | 203 | [super didReceiveMemoryWarning]; |
| 68 | 204 | // Dispose of any resources that can be recreated. | ... | ... |
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/Controller/LVCLivePlayerController.m
| ... | ... | @@ -261,6 +261,7 @@ |
| 261 | 261 | [[CNLiveChatManager sharedCNLiveChatManager] quitChatRoom:_roomId success:NULL error:NULL]; |
| 262 | 262 | |
| 263 | 263 | self.navigationController.navigationBar.hidden = NO; |
| 264 | + self.tabBarController.tabBar.hidden = NO; | |
| 264 | 265 | [self.navigationController popViewControllerAnimated:YES]; |
| 265 | 266 | } |
| 266 | 267 | } | ... | ... |
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/LVCPlayer.m
| ... | ... | @@ -11,6 +11,9 @@ |
| 11 | 11 | #import "SevenSwitch.h" |
| 12 | 12 | |
| 13 | 13 | @interface LVCPlayer ()<UIGestureRecognizerDelegate> |
| 14 | +{ | |
| 15 | + LVCChannelDetailsModel *_model; | |
| 16 | +} | |
| 14 | 17 | |
| 15 | 18 | @property (nonatomic, strong) UIButton *backBtn; //返回 |
| 16 | 19 | @property (nonatomic, strong) UIButton *playOrPauseBtn; //播放/暂停 |
| ... | ... | @@ -31,6 +34,7 @@ |
| 31 | 34 | { |
| 32 | 35 | self = [super initWithFrame:frame]; |
| 33 | 36 | if (self) { |
| 37 | + _model = model; | |
| 34 | 38 | |
| 35 | 39 | [self initPlayerWithModel:model]; |
| 36 | 40 | |
| ... | ... | @@ -57,7 +61,7 @@ |
| 57 | 61 | { |
| 58 | 62 | /* |
| 59 | 63 | */ |
| 60 | - _player = [[CNLiveMoviePlayerController alloc] initLivePlayWithChannelId:model.mediaId authSuccess:^{ | |
| 64 | + _player = [[CNLiveMoviePlayerController alloc] initLivePlayWithChannelId:[NSString stringWithFormat:@"82_%@",model.mediaId] authSuccess:^{ | |
| 61 | 65 | [self addObservers]; |
| 62 | 66 | _player.videoDecoderMode = CNLiveMovieVideoDecoderMode_AUTO; |
| 63 | 67 | _player.shouldAutoplay = YES; |
| ... | ... | @@ -549,7 +553,7 @@ |
| 549 | 553 | { |
| 550 | 554 | if (!_titleLab) { |
| 551 | 555 | _titleLab = [[UILabel alloc] init]; |
| 552 | - _titleLab.text = @"我是标题~~"; | |
| 556 | + _titleLab.text = _model.title; | |
| 553 | 557 | _titleLab.textColor = [UIColor whiteColor]; |
| 554 | 558 | _titleLab.font = [UIFont systemFontOfSize:17]; |
| 555 | 559 | } | ... | ... |
LiveVideoCloud/LiveVideoCloud/Classes/Sections/homeSections/View/LVCTelevisionView.m
| ... | ... | @@ -190,7 +190,7 @@ static NSString *otherHeaderId = @"LVCOtherHeaderReusableView"; |
| 190 | 190 | |
| 191 | 191 | LVCChannelsModel *model = _channelsModelArray[indexPath.section - 1]; |
| 192 | 192 | LVCChannelDetailsModel *details = model.programs[indexPath.item]; |
| 193 | - self.viewController.hidesBottomBarWhenPushed = YES; | |
| 193 | + self.viewController.tabBarController.tabBar.hidden = YES; | |
| 194 | 194 | |
| 195 | 195 | LVCLivePlayerController *playVC = [[LVCLivePlayerController alloc] init]; |
| 196 | 196 | playVC.model = details; |
| ... | ... | @@ -272,7 +272,7 @@ static NSString *otherHeaderId = @"LVCOtherHeaderReusableView"; |
| 272 | 272 | layout.sectionInset = UIEdgeInsetsMake(6, 10, 0, 10); |
| 273 | 273 | _collectionView.showsHorizontalScrollIndicator = NO; |
| 274 | 274 | |
| 275 | - _collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) collectionViewLayout:layout]; | |
| 275 | + _collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT-64-49) collectionViewLayout:layout]; | |
| 276 | 276 | _collectionView.backgroundColor = [UIColor whiteColor]; |
| 277 | 277 | |
| 278 | 278 | [_collectionView registerClass:[LVCLiveListCollectionViewCell class] forCellWithReuseIdentifier:cellId]; | ... | ... |
LiveVideoCloud/LiveVideoCloud/PrefixHeader.pch
LiveVideoCloud/LiveVideoCloud/UtilKits/Category/NSArray+Safety.h
0 → 100755
| 1 | +// | |
| 2 | +// NSArray+Safety.h | |
| 3 | +// CNLive | |
| 4 | +// | |
| 5 | +// Created by 雷浩杰 on 15/9/1. | |
| 6 | +// Copyright (c) 2015年 雷浩杰. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import <Foundation/Foundation.h> | |
| 10 | + | |
| 11 | +@interface NSArray (Safety) | |
| 12 | + | |
| 13 | +- (nullable id)safetyObjectAtIndex:(NSUInteger)index; | |
| 14 | + | |
| 15 | +- (nullable id)randomObject; | |
| 16 | + | |
| 17 | +@end | ... | ... |
LiveVideoCloud/LiveVideoCloud/UtilKits/Category/NSArray+Safety.m
0 → 100755
| 1 | +// | |
| 2 | +// NSArray+Safety.m | |
| 3 | +// CNLive | |
| 4 | +// | |
| 5 | +// Created by 雷浩杰 on 15/9/1. | |
| 6 | +// Copyright (c) 2015年 雷浩杰. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "NSArray+Safety.h" | |
| 10 | + | |
| 11 | +@implementation NSArray (Safety) | |
| 12 | + | |
| 13 | +- (nullable id)safetyObjectAtIndex:(NSUInteger)index | |
| 14 | +{ | |
| 15 | + if (!self || self.count == 0 || self.count <= index) { | |
| 16 | + return nil; | |
| 17 | + } | |
| 18 | + | |
| 19 | + return self[index]; | |
| 20 | +} | |
| 21 | + | |
| 22 | +- (nullable id)randomObject | |
| 23 | +{ | |
| 24 | + if (!self || ![self isKindOfClass:[NSArray class]] || self.count == 0) { | |
| 25 | + return nil; | |
| 26 | + } | |
| 27 | + int i = arc4random()%self.count; | |
| 28 | + return [self safetyObjectAtIndex:i]; | |
| 29 | +} | |
| 30 | + | |
| 31 | +@end | ... | ... |