【iOS】ZARA仿寫
文章目錄
- 【iOS】ZARA仿寫
- 前言
- 首頁
- 發現
- 我的
- 對姓名的更改
- 總結
前言
暑假第一個的任務仿寫ZARA 雖然不是特別難卻有很多小細節需要注意
首頁
點進程序出現的就是整個項目最主要的一個點,即首頁的無限輪播圖,不管是自動輪播還是手動滑動,前后圖片的滑動都非常絲滑,即在視覺上有一種無限輪播效果,我這里面的具體思路是插入比你想看到的圖片多兩張圖,即在第一張圖前面插入最后一張圖的假圖,在最后一張圖后面插入第一張圖片的假圖,當滾動到假圖時悄悄跳回真實內容位置,視覺上實現 “無縫循環“
插入假圖代碼:
self.images = @[@"zara1.jpg", @"zara2.jpg", @"zara3.jpg", @"zara4.jpg", @"zara5.jpg"];
for (int i = 0; i < self.images.count + 2; i++) {NSString *imageName;if (i == 0) {imageName = [self.images lastObject];} else if (i == self.images.count + 1) {imageName = [self.images firstObject];} else {imageName = self.images[i - 1];}UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];imageView.frame = CGRectMake(bounds.size.width * i, 0, bounds.size.width, bounds.size.height - 280);imageView.contentMode = UIViewContentModeScaleAspectFit;[self.scrollView addSubview:imageView];}
自動播放,是用NSTimer定時滑動,并在滑動后進行自動檢測修正
- (void)startTimerScollView {self.timerScrollView = [NSTimer scheduledTimerWithTimeInterval: 2.5 target: self selector: @selector(pageToNext) userInfo: self repeats: YES];[[NSRunLoop mainRunLoop] addTimer:self.timerScrollView forMode:NSRunLoopCommonModes];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;NSInteger pageIndex = scrollView.contentOffset.x / screenWidth;if (pageIndex == 0) {[scrollView setContentOffset:CGPointMake(screenWidth * self.images.count, 0) animated:NO];self.segmentView.selectedSegmentIndex = self.images.count - 1;} else if (pageIndex == self.images.count + 1) {[scrollView setContentOffset:CGPointMake(screenWidth, 0) animated:NO];self.segmentView.selectedSegmentIndex = 0;} else {self.segmentView.selectedSegmentIndex = pageIndex - 1;}
}
還有一點就是設置拖動時的視圖不可移動,以及在拖動前后,對定時器的銷毀和重新建立
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {[self.timerScrollView invalidate];self.timerScrollView = nil;self.isDragging = YES;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {self.timerScrollView = [NSTimer scheduledTimerWithTimeInterval: 2.5 target: self selector: @selector(pageToNext) userInfo: self repeats: YES];self.isDragging = NO;
}
然后對于下面的頁數的指示器可以使用UIPageControl或者設置無字且較小的UISegmentedControl控件來展示
首頁效果圖:
發現
對發現這一頁沒什么好說的,跟首頁基本一樣,只不過需要關閉自動滑動的內容,只允許用戶手動滑動,再在屏幕上方安置一個分欄控件
- (void)setupSegmentView {CGRect bounds = self.view.bounds;self.segmentView = [[UISegmentedControl alloc] initWithItems:@[@"男裝", @"女裝", @"童裝"]];self.segmentView.frame = CGRectMake(10, 110, bounds.size.width - 20, 50);[self.segmentView addTarget:self action:@selector(segmentChanged:) forControlEvents:UIControlEventValueChanged];self.segmentView.selectedSegmentIndex = 0;[self.view addSubview:self.segmentView];
}
我的
這個界面主要是一個自定義cell的應用,在之前的播客講過,這里主要通過不同的section索引來進行不同單元格的繪制
- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.self.view.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.7];UILabel *titleLable = [[UILabel alloc] init];titleLable.text = @"個人主頁";titleLable.frame = CGRectMake(168, 60, 200, 30);self.tableView = [[UITableView alloc] initWithFrame: self.view.bounds style: UITableViewStyleGrouped];self.tableView.delegate = self;self.tableView.dataSource = self;//self.tableView.backgroundColor = [UIColor grayColor];[self.tableView registerClass: [MyTableViewCell class] forCellReuseIdentifier: str];[self.view addSubview: self.tableView];[self.view addSubview: titleLable];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {switch (section) {case 0:return 1;break;case 1:return 5;break;default:break;}return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {if (indexPath.section == 0) {return 130;} else if (indexPath.section == 1) {return 60;}return 0;
}
對姓名的更改
在對姓名的更更改這里涉及了多界面傳值中協議傳值的一部分知識
通過設置 delegate 屬性,并實現協議方法來實現從內層視圖把name傳回ThirdVC界面的傳值邏輯
定義協議與代理屬性:
@protocol ProfileViewControllerDelegate <NSObject>
- (void)profileViewController:(ProfileViewController *)controller didUpdateName:(NSString *)name;
@end
@property (nonatomic, weak) id<ProfileViewControllerDelegate> delegate;
實現協議方法用于傳值
- (void)profileViewController:(ProfileViewController *)controller didUpdateName:(NSString *)name {if (!name || name.length == 0) {return;}NSIndexPath *targetIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];MyTableViewCell *cell = (MyTableViewCell *)[self.tableView cellForRowAtIndexPath:targetIndexPath];if (cell) {cell.nameLabel.text = name;} else {[self.tableView reloadRowsAtIndexPaths:@[targetIndexPath] withRowAnimation:UITableViewRowAnimationNone];}self.userName = name;
}
其他有關傳值的方法我會在后面學習后寫出
效果圖:
總結
剛開始第一個項目難度不是特別大,但是可能開始的時候對寫的邏輯會不清晰從而導致寫的時候會比較麻煩或者思路混亂,寫的時候還是得理清思路,這樣寫的時候也會事半功倍