第一次修改:2017-09-29:對(duì)iOS 11進(jìn)行兼容
前言:最近一直在看Effective Objective-C這本書涤垫,也有在做筆記,打算看完之后寫一篇Effective Objective-C的總結(jié)厂抖,說一下自己的看法和收獲。
言歸正傳克懊,最近項(xiàng)目要實(shí)現(xiàn)一個(gè)類似于京東/淘寶下拉查看商品詳情的功能忱辅,自己就先寫了一個(gè)小的demo七蜘,實(shí)現(xiàn)方式很簡(jiǎn)單,在這里做下記錄與分享墙懂,如有需要改進(jìn)的地方橡卤,歡迎留言探討?。
Github:看這里
testGif.gif
思路整理:
首先分析界面布局损搬,我先是嘗試使用一個(gè)scrollView包含兩個(gè)contentView的方式進(jìn)行實(shí)現(xiàn)碧库,發(fā)現(xiàn)實(shí)現(xiàn)起來(lái)比較繁瑣,因?yàn)檫@樣一來(lái)當(dāng)前界面就會(huì)產(chǎn)生兩到三個(gè)scrollView巧勤,對(duì)偏移值的觀察處理會(huì)比較麻煩嵌灰。嘗試失敗后我就使用了另一種方式進(jìn)行實(shí)現(xiàn)。發(fā)現(xiàn)類似的界面一般分為三部分:
- 展示部分視圖颅悉,包含scrollView
- 詳情部分視圖伞鲫,包含scrollView
- 上下拉時(shí)提示視圖
/**
首頁(yè)視圖
*/
@property (nonatomic, strong) UIScrollView *firstScrollView;
/**
上拉視圖
*/
@property (nonatomic, strong) UIView *footView;
/**
上拉箭頭
*/
@property (nonatomic, strong) UIImageView *footArrowView;
/**
上拉文字
*/
@property (nonatomic, strong) UILabel *footLabel;
/**
下拉視圖
*/
@property (nonatomic, strong) UIView *headView;
/**
下拉箭頭
*/
@property (nonatomic, strong) UIImageView *headArrowView;
/**
下拉文字
*/
@property (nonatomic, strong) UILabel *headLabel;
/**
詳情頁(yè)
*/
@property (nonatomic, strong) UIView *secondView;
/**
詳情頁(yè)scrollView
*/
@property (nonatomic, strong) UIWebView *secondScrollView;
構(gòu)建UI:實(shí)例化三部分視圖,并為scrollView設(shè)置代理签舞,通過代理方法監(jiān)聽偏移值
- (void)createUI{
self.title = @"testProduct";
self.view.backgroundColor = [UIColor whiteColor];
self.automaticallyAdjustsScrollViewInsets = NO;
[self.view addSubview:self.firstScrollView];
[self.view addSubview:self.secondView];
}
- (UIScrollView *)firstScrollView{
if (!_firstScrollView) {
_firstScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 64, KScreenWidth, KScreenHeight-64)];
_firstScrollView.backgroundColor = KColorRGB(200, 160, 110);
_firstScrollView.contentSize = CGSizeMake(0, KScreenHeight);
_firstScrollView.pagingEnabled = YES;
_firstScrollView.showsVerticalScrollIndicator = NO;
_firstScrollView.showsHorizontalScrollIndicator = NO;
_firstScrollView.delegate = self;
UILabel *label = [MyControl labelWithTitle:@"firstView" fram:CGRectMake(0, 200, KScreenWidth, 40) fontOfSize:20];
label.textAlignment = NSTextAlignmentCenter;
[_firstScrollView addSubview:label];
[_firstScrollView addSubview:self.footView];
}
return _firstScrollView;
}
- (UIView *)footView{
if (!_footView) {
_footView = [[UIView alloc]initWithFrame:CGRectMake(0, KScreenHeight-60-64, KScreenWidth, 40)];
_footArrowView = [[UIImageView alloc]initWithFrame:CGRectMake((KScreenWidth-200)/2, 10, 15, 20)];
_footArrowView.image = [UIImage imageNamed:@"pullArrow"];
[_footView addSubview:_footArrowView];
_footLabel = [MyControl labelWithTitle:@"上拉查看詳情" fram:CGRectMake((KScreenWidth-200)/2+50, 0, 150, 40) fontOfSize:14];
[_footView addSubview:_footLabel];
}
return _footView;
}
- (UIView *)secondView{
if (!_secondView) {
_secondView = [[UIView alloc]initWithFrame:CGRectMake(0, KScreenHeight+20, KScreenWidth, KScreenHeight)];
_secondView.backgroundColor = KColorRGB(241, 241, 241);
UILabel *label = [MyControl labelWithTitle:@"項(xiàng)目詳細(xì)" fram:CGRectMake(0, 0, KScreenWidth, 50) fontOfSize:17];
label.textAlignment = NSTextAlignmentCenter;
label.backgroundColor = [UIColor whiteColor];
[_secondView addSubview:self.secondScrollView];
[_secondView addSubview:label];
}
return _secondView;
}
- (UIWebView *)secondScrollView{
if (!_secondScrollView) {
_secondScrollView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 51, KScreenWidth, KScreenHeight-51-64)];
_secondScrollView.backgroundColor = KColorRGB(192, 192, 192);
[_secondScrollView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:URL]]];
_secondScrollView.scrollView.delegate = self;
[_secondScrollView.scrollView addSubview:self.headView];
}
return _secondScrollView;
}
交互處理:
- 用戶拖拽時(shí)根據(jù)偏移值動(dòng)態(tài)改變上/下拉提醒視圖的展示效果。
(1)改變箭頭指向
(2)改變提示文字 - 拖拽結(jié)束時(shí)根據(jù)當(dāng)前偏移值對(duì)界面進(jìn)行處理:
(1)上拉達(dá)到臨界點(diǎn)柒瓣,改變首頁(yè)和詳情頁(yè)的fram儒搭;
(2)下拉達(dá)到臨界點(diǎn),改變首頁(yè)和詳情頁(yè)的fram芙贫;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
NSLog(@"didscroll");
CGFloat y = scrollView.contentOffset.y;
if (scrollView == _firstScrollView) {
self.secondView.transform = CGAffineTransformMakeTranslation(0, -y);
if (y < 60) {
self.footLabel.text = @"上拉查看詳情";
self.footArrowView.transform = CGAffineTransformIdentity;
}else{
self.footLabel.text = @"松開查看詳情";
self.footArrowView.transform = CGAffineTransformMakeRotation(M_PI);
}
}
if ([scrollView isEqual:_secondScrollView.scrollView]) {
CGAffineTransform transform = CGAffineTransformIdentity;
if (y < -60) {
self.headLabel.text = @"松開回到首頁(yè)";
}else {
transform = CGAffineTransformMakeRotation(M_PI);
self.headLabel.text = @"下拉回到首頁(yè)";
}
self.headArrowView.transform = transform;
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
CGFloat y = scrollView.contentOffset.y;
if ([scrollView isEqual:_firstScrollView]) {
if (y > 60){
[self transformToSecondView];
}
}
if ([scrollView isEqual:_secondScrollView.scrollView]) {
if (y < -60) {
[self transformToFirstView];
}
}
}
動(dòng)態(tài)改變首頁(yè)和詳情頁(yè)的fram:
- (void)transformToSecondView{
[UIView animateWithDuration:0.5 animations:^{
CGRect rect1 = _firstScrollView.frame;
CGRect rect2 = _secondView.frame;
rect1.origin.y = -KScreenHeight;
rect2.origin.y = 0;
self.firstScrollView.frame = rect1;
self.secondView.frame = rect2;
} completion:^(BOOL finished) {
self.footArrowView.transform = CGAffineTransformIdentity;
self.footLabel.text = @"上拉查看詳情";
}];
}
- (void)transformToFirstView{
[UIView animateWithDuration:0.5 animations:^{
CGRect rect1 = _firstScrollView.frame;
CGRect rect2 = _secondView.frame;
rect1.origin.y = 64;
rect2.origin.y = KScreenHeight+20;
self.firstScrollView.frame = rect1;
self.secondView.frame = rect2;
} completion:^(BOOL finished) {
self.headArrowView.transform = CGAffineTransformIdentity;
self.headLabel.text = @"下拉回到首頁(yè)";
}];
}