ios中创建单例的作用(模仿网易新闻客户端)

来源:互联网 发布:零食数据 编辑:程序博客网 时间:2024/06/03 18:17

近下载了一个网易新闻的APP客户端,觉得新闻主页的滚动效果不错,每个标题都对应一个版面,如图


不好意思图有点大(是在网上下的,我就懒得截图了)

于是就模仿它写了一个demo程序.代码如下所示...

MainViewController是APP的主界面,负责初始化头部的scrollView以及底下的scrollView,在AppDelegate实现类中初始化该对象并设置根视图为它。


[objc] view plain copy
  1. //  MainViewController.h    
  2. //  test4101    
  3. //    
  4. //  Created by silicon on 14-4-10.    
  5. //  Copyright (c) 2014年 silicon. All rights reserved.    
  6. //    
  7.     
  8. #import <UIKit/UIKit.h>    
  9.     
  10. @interface MainViewController : UIViewController    
  11.     
  12. @end</pre><br>    
  13. <br>     
  14.     
  15. <pre code_snippet_id="346326" snippet_file_name="blog_20140515_10_816282"></pre><pre code_snippet_id="346326" snippet_file_name="blog_20140515_29_2384508" name="code" class="objc"></pre><pre code_snippet_id="346326" snippet_file_name="blog_20140515_29_2384508" name="code" class="objc"></pre><pre code_snippet_id="346326" snippet_file_name="blog_20140515_29_2384508" name="code" class="objc"></pre><pre code_snippet_id="346326" snippet_file_name="blog_20140515_29_2384508" name="code" class="objc"></pre><pre code_snippet_id="346326" snippet_file_name="blog_20140515_13_2540906" name="code" class="objc">//    
  16. //  MainViewController.m    
  17. //  test4101    
  18. //    
  19. //  Created by silicon on 14-4-10.    
  20. //  Copyright (c) 2014年 silicon. All rights reserved.    
  21. //    
  22.     
  23. #import "MainViewController.h"    
  24. #import "TopScrollView.h"    
  25. #import "ButtomScrollView.h"    
  26.     
  27. @interface MainViewController ()    
  28.     
  29. @end    
  30.     
  31. @implementation MainViewController    
  32.     
  33. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil    
  34. {    
  35.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];    
  36.     if (self) {    
  37.         // Custom initialization    
  38.     }    
  39.     return self;    
  40. }    
  41.     
  42. - (void)viewDidLoad    
  43. {    
  44.     [super viewDidLoad];    
  45.     // Do any additional setup after loading the view from its nib.    
  46.     
  47.     UIImageView *topShadowImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0443205)];    
  48.     [topShadowImageView setImage:[UIImage imageNamed:@"top_background_shadow.png"]];    
  49.     [self.view addSubview:topShadowImageView];    
  50.         
  51.     TopScrollView *topScrollView = [TopScrollView getInstance];    
  52.     ButtomScrollView *buttomScrollView = [ButtomScrollView getInstance];    
  53.         
  54.     topScrollView.titleArray = @[@"苹果中国"@"iCloud"@"新浪微薄"@"维基百科"@"百度"@"中国雅虎"@"新闻"@"流行"];    
  55.     buttomScrollView.viewNameArray = @[@"苹果中国"@"iCloud"@"新浪微薄"@"维基百科"@"百度"@"中国雅虎"@"新闻"@"流行"];    
  56.         
  57.     [self.view addSubview:topScrollView];    
  58.     [self.view addSubview:buttomScrollView];    
  59.         
  60.     [topScrollView initWithTitleButtons];    
  61.     [buttomScrollView initWithViews];    
  62. }    
  63.     
  64. - (void)didReceiveMemoryWarning    
  65. {    
  66.     [super didReceiveMemoryWarning];    
  67.     // Dispose of any resources that can be recreated.    
  68. }    
  69.     
  70. @end  

TopScrollView这个类主要用于控制上面标题的滚动逻辑,通过initWithTitleButtons这个函数来初始化按钮(包括按钮的标题,tag, 响应事件,坐标)并且将按钮的

x坐标以及宽度存储到容器中保存(相应读取可以按照控件的tag来取)。

selectNameButton用来控制按钮切换以及底部试图同步切换的逻辑。

adjustScrollViewContentX函数用于控制当按钮的x坐标超过了屏幕的最大宽时,调整按钮的x坐标至屏幕可见范围。

[objc] view plain copy
  1. //  TopScrollView.h    
  2. //  test4101    
  3. //    
  4. //  Created by silicon on 14-4-10.    
  5. //  Copyright (c) 2014年 silicon. All rights reserved.    
  6. //    
  7.     
  8. #import <UIKit/UIKit.h>    
  9.     
  10. @interface TopScrollView : UIScrollView <UIScrollViewDelegate>{    
  11.     NSArray *titleArray;    
  12.     NSInteger userSelectedButtonTag;    
  13.     NSInteger scrollViewSelectedID;    
  14.     UIImageView *shadowImage;    
  15. }    
  16.     
  17. @property (nonatomicretainNSArray *titleArray;    
  18.     
  19. @property (nonatomicretainNSMutableArray *buttonWithArray;    
  20.     
  21. @property (nonatomicretainNSMutableArray *buttonOrignXArray;    
  22.     
  23. @property (assign) NSInteger scrollViewSelectedID;    
  24.     
  25. @property (assign) NSInteger userSelectedButtonTag;    
  26.     
  27.     
  28. + (TopScrollView *)getInstance;    
  29.     
  30. //加载顶部标题    
  31. - (void)initWithTitleButtons;    
  32.     
  33. - (void)setButttonUnSelect;    
  34.     
  35. - (void)setButtonSelect;    
  36.     
  37. - (void)setScrollViewContentOffset;    
  38.     
  39. @end  

[objc] view plain copy
  1. //  TopScrollView.m    
  2. //  test4101    
  3. //    
  4. //  Created by silicon on 14-4-10.    
  5. //  Copyright (c) 2014年 silicon. All rights reserved.    
  6. //    
  7.     
  8. #import "TopScrollView.h"    
  9. #import "ButtomScrollView.h"    
  10.     
  11. @implementation TopScrollView    
  12. @synthesize titleArray;    
  13. @synthesize userSelectedButtonTag;    
  14. @synthesize scrollViewSelectedID;    
  15. @synthesize buttonOrignXArray;    
  16. @synthesize buttonWithArray;    
  17.     
  18. + (TopScrollView *)getInstance{    
  19.     static TopScrollView *instance;    
  20.     static dispatch_once_t onceToken;    
  21.     dispatch_once(&onceToken, ^{    
  22.         instance = [[self alloc] initWithFrame:CGRectMake(020, CONTENTSIZEX, 44)];    
  23.     });    
  24.     return instance;    
  25. }    
  26.     
  27. - (id)initWithFrame:(CGRect)frame    
  28. {    
  29.     self = [super initWithFrame:frame];    
  30.     if (self) {    
  31.         // Initialization code    
  32.         self.delegate = self;    
  33.         self.backgroundColor = [UIColor clearColor];    
  34.         self.pagingEnabled = NO;    
  35.         self.showsHorizontalScrollIndicator = NO;    
  36.         self.showsVerticalScrollIndicator = NO;    
  37.             
  38.         userSelectedButtonTag = 100;    
  39.         scrollViewSelectedID = 100;    
  40.             
  41.         self.buttonOrignXArray = [[NSMutableArray alloc] init];    
  42.         self.buttonWithArray = [[NSMutableArray alloc] init];    
  43.     }    
  44.     return self;    
  45. }    
  46.     
  47. - (void)initWithTitleButtons{    
  48.         
  49.     float xPos = 5.0f;    
  50.     for(int i = 0; i < [self.titleArray count]; i++){    
  51.         UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];    
  52.         NSString *title = [self.titleArray objectAtIndex:i];    
  53.         [button setTag:i + 100];    
  54.         if(i == 0){    
  55.             button.selected = YES;    
  56.         }    
  57.         [button setTitle:title forState:UIControlStateNormal];    
  58.         [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];    
  59.         [button addTarget:self action:@selector(selectNameButton:) forControlEvents:UIControlEventTouchUpInside];    
  60.             
  61.         int buttonWidth = [title sizeWithFont:button.titleLabel.font    
  62.                             constrainedToSize:CGSizeMake(15030)    
  63.                                 lineBreakMode:NSLineBreakByClipping].width;    
  64.         
  65.         button.frame = CGRectMake(xPos, 9, buttonWidth + BUTTONGAP, 30);    
  66.         [buttonOrignXArray addObject:@(xPos)];    
  67.         //按钮的X坐标    
  68.         xPos += buttonWidth + BUTTONGAP;    
  69.         //按钮的宽度    
  70.         [self.buttonWithArray addObject:@(button.frame.size.width)];    
  71.         [self addSubview:button];    
  72.     }    
  73.     //视图的位移    
  74.     self.contentSize = CGSizeMake(xPos, 44);    
  75.     shadowImage = [[UIImageView alloc] initWithFrame:CGRectMake(BUTTONGAP, 0,    
  76.                                                                 [[self.buttonWithArray objectAtIndex:0] floatValue],    
  77.                                                                 44)];    
  78.     [shadowImage setImage:[UIImage imageNamed:@"red_line_and_shadow.png"]];    
  79.     [self addSubview:shadowImage];    
  80. }    
  81.     
  82. - (void)selectNameButton:(UIButton *)sender{    
  83.     [self adjustScrollViewContentX:sender];    
  84.         
  85.     //如果跟换按钮    
  86.     if(sender.tag != userSelectedButtonTag){    
  87.         UIButton *mybutton = (UIButton *)[self viewWithTag:userSelectedButtonTag];    
  88.         mybutton.selected = NO;    
  89.         userSelectedButtonTag = sender.tag;    
  90.     }    
  91.     //按钮选中状态    
  92.     if(!sender.selected){    
  93.         sender.selected = YES;    
  94.         [UIView animateWithDuration:0.25 animations:^{    
  95.             [shadowImage setFrame:CGRectMake(sender.frame.origin.x,    
  96.                                              0,    
  97.                                              [[self.buttonWithArray objectAtIndex:sender.tag - 100] floatValue],    
  98.                                              44)];    
  99.         } completion:^(BOOL finished) {    
  100.             if(finished){    
  101.                 //页面出现    
  102.                 [[ButtomScrollView getInstance] setContentOffset:CGPointMake((sender.tag - 100) * 3200) animated:YES];    
  103.                 //滑动选择页面    
  104.                 scrollViewSelectedID = sender.tag;    
  105.             }    
  106.         }];    
  107.     }    
  108. }    
  109.     
  110. //调整滚动按钮显示    
  111. - (void)adjustScrollViewContentX:(UIButton *)sender{    
  112.     float originX = [[self.buttonOrignXArray objectAtIndex:(sender.tag - 100)] floatValue];    
  113.     float width = [[self.buttonWithArray objectAtIndex:(sender.tag - 100)] floatValue];    
  114.     
  115.     if((sender.frame.origin.x - self.contentOffset.x) > (CONTENTSIZEX - (BUTTONGAP + width))){    
  116.         [self setContentOffset:CGPointMake(originX - 300) animated:YES];    
  117.     }    
  118.         
  119.     if((sender.frame.origin.x - self.contentOffset.x) < 5){    
  120.         [self setContentOffset:CGPointMake(originX, 0) animated:YES];    
  121.     }    
  122. }    
  123.     
  124. - (void)setButttonUnSelect{    
  125.     UIButton *button = (UIButton *)[self viewWithTag:scrollViewSelectedID];    
  126.     button.selected = NO;    
  127. }    
  128.     
  129. - (void)setButtonSelect{    
  130.     //选中滑动的按钮    
  131.     UIButton *button = (UIButton *)[self viewWithTag:scrollViewSelectedID];    
  132.     [UIView animateWithDuration:0.25 animations:^{    
  133.         [shadowImage setFrame:CGRectMake(button.frame.origin.x0,    
  134.                                          [[self.buttonWithArray objectAtIndex:button.tag - 100] floatValue],    
  135.                                          44)];    
  136.     } completion:^(BOOL finished) {    
  137.         if(finished){    
  138.             if(!button){    
  139.                 button.selected = YES;    
  140.                 userSelectedButtonTag = button.tag;    
  141.             }    
  142.         }    
  143.     }];    
  144. }    
  145.     
  146. - (void)setScrollViewContentOffset{    
  147.     float originX = [[self.buttonOrignXArray objectAtIndex:(scrollViewSelectedID - 100)] floatValue];    
  148.     float width = [[self.buttonWithArray objectAtIndex:(scrollViewSelectedID - 100)] floatValue];    
  149.         
  150.     if((originX - self.contentOffset.x) > (CONTENTSIZEX - (BUTTONGAP + width))){    
  151.         [self setContentOffset:CGPointMake(originX - 300) animated:YES];    
  152.     }    
  153.         
  154.     if(originX - self.contentOffset.x < 5){    
  155.         [self setContentOffset:CGPointMake(originX, 0) animated:YES];    
  156.     }    
  157. }    
  158.     
  159. @end  

ButtomScrollView这个类主要控制底部视图的显示, adjustTopScrollViewButton函数用于调整按钮的显示,相关逻辑见源码(打字打的有点手酸)...

[objc] view plain copy
  1. //  ButtomScrollView.h    
  2. //  test4101    
  3. //    
  4. //  Created by silicon on 14-4-10.    
  5. //  Copyright (c) 2014年 silicon. All rights reserved.    
  6. //    
  7.     
  8. #import <UIKit/UIKit.h>    
  9.     
  10. @interface ButtomScrollView : UIScrollView<UIScrollViewDelegate>{    
  11.     NSMutableArray *viewNameArray;    
  12.     CGFloat userContentOffsetX;    
  13.     BOOL isLeftScroll;    
  14. }    
  15.     
  16. @property (nonatomicretainNSArray *viewNameArray;    
  17.     
  18. + (ButtomScrollView *)getInstance;    
  19.     
  20. - (void)initWithViews;    
  21.     
  22. - (void)loadData;    
  23.     
  24.     
  25. @end  


[objc] view plain copy
  1. //  ButtomScrollView.m    
  2. //  test4101    
  3. //    
  4. //  Created by silicon on 14-4-10.    
  5. //  Copyright (c) 2014年 silicon. All rights reserved.    
  6. //    
  7.     
  8. #import "ButtomScrollView.h"    
  9. #import "TopScrollView.h"    
  10.     
  11.     
  12. @implementation ButtomScrollView    
  13. @synthesize viewNameArray;    
  14.     
  15. - (id)initWithFrame:(CGRect)frame    
  16. {    
  17.     self = [super initWithFrame:frame];    
  18.     if (self) {    
  19.         // Initialization code    
  20.         self.delegate = self;    
  21.         self.backgroundColor = [UIColor lightGrayColor];    
  22.         self.pagingEnabled = YES;    
  23.         self.userInteractionEnabled = YES;    
  24.         self.bounces = NO;    
  25.         
  26.         self.showsHorizontalScrollIndicator = NO;    
  27.         self.showsVerticalScrollIndicator = NO;    
  28.             
  29.         userContentOffsetX = 0;    
  30.     }    
  31.     return self;    
  32. }    
  33.     
  34. + (ButtomScrollView *)getInstance{    
  35.     static ButtomScrollView *instance;    
  36.     static dispatch_once_t onceToken;    
  37.     dispatch_once(&onceToken, ^{    
  38.         instance = [[self alloc] initWithFrame:CGRectMake(064, CONTENTSIZEX, 500)];    
  39.     });    
  40.     return instance;    
  41. }    
  42.     
  43. - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{    
  44.     userContentOffsetX = scrollView.contentOffset.x;    
  45. }    
  46.     
  47. - (void)scrollViewDidScroll:(UIScrollView *)scrollView{    
  48.     if(userContentOffsetX < scrollView.contentOffset.x){    
  49.         isLeftScroll = YES;    
  50.     }else{    
  51.         isLeftScroll = NO;    
  52.     }    
  53. }    
  54.     
  55. - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{    
  56.     [self adjustTopScrollViewButton:scrollView];    
  57.     [self loadData];    
  58. }    
  59.     
  60. //调整按钮显示    
  61. - (void)adjustTopScrollViewButton:(UIScrollView *)scrollView{    
  62.     [[TopScrollView getInstance] setButttonUnSelect];    
  63.     [TopScrollView getInstance].scrollViewSelectedID = POSITION + 100;    
  64.     [[TopScrollView getInstance] setButtonSelect];    
  65.     [[TopScrollView getInstance] setScrollViewContentOffset];    
  66. }    
  67.     
  68. - (void)initWithViews{    
  69.     for(int i = 0; i < [viewNameArray count]; i++){    
  70.         UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50 + 320*i, 100320self.frame.size.height - 44)];    
  71.         label.tag = 200 + i;    
  72.         if(i == 0){    
  73.             label.text = [viewNameArray objectAtIndex:i];    
  74.         }    
  75.         [self addSubview:label];    
  76.     }    
  77.         
  78.     self.contentSize = CGSizeMake(320*[viewNameArray count], self.frame.size.height - 44);    
  79. }    
  80.     
  81. - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView    
  82. {    
  83.     [self loadData];    
  84. }    
  85.     
  86. - (void)loadData{    
  87.     CGFloat pageWidth = self.frame.size.width;    
  88.     int page = floor((self.contentOffset.x - pageWidth/viewNameArray.count)/pageWidth) + 1;    
  89.     UILabel *label = (UILabel *)[self viewWithTag:page + 200];    
  90.     label.text = [NSString stringWithFormat:@"%@", [viewNameArray objectAtIndex:page]];    
  91. }  

BTW,别忘了在Prefix文件中加入以下宏。

[objc] view plain copy
  1. //  Prefix header    
  2. //    
  3. //  The contents of this file are implicitly included at the beginning of every source file.    
  4. //    
  5.     
  6. #import <Availability.h>    
  7.     
  8. #ifndef __IPHONE_3_0    
  9. #warning "This project uses features only available in iOS SDK 3.0 and later."    
  10. #endif    
  11.     
  12. #define BUTTONGAP 10    
  13. #define CONTENTSIZEX 320    
  14. #define POSITION (int)(scrollView.contentOffset.x/320)    
  15.     
  16. #ifdef __OBJC__    
  17.     #import <UIKit/UIKit.h>    
  18.     #import <Foundation/Foundation.h>    
  19. #endif  

好了,以上就是该demo的源码,运行一下,如下图所以.



点击iCloud按钮,下面也随即切换到iCloud。



以上就是今天这篇文章所讲的全部内容了,希望大家指出问题,一起进步啊! 





阅读全文
0 0