iOS 網易新聞首頁進化版Demo(MXSegmentedPager),內建平行頭部展開

來源:互聯網
上載者:User

標籤:

      網易新聞首頁類似的介面簡直太常見了,需求不同自然做出來的效果不同了,之前

用ScrollView寫過一個控制器的封裝,但是這雷根本沒有考慮到控制器的複用以及預加

載機制,如果沒考慮複用的話當介面爆炸的時候估計你的App會很卡,例如半塘這樣

的,我抓包發現貌似會預先載入當前介面後三個介面,讓使用者滑動的時候能第一時間看到

資料,這樣的機制蠻不錯的,今天來介紹個能複用的架構,順帶介紹個另一個高斯模糊

的Catagory。




這裡的三個介面分別是最普通的控制器,webview以及雙TableView


該架構有兩種用法,第一種直接建立一個ViewController繼承它,第二個就是在控制器寫成屬性


這裡我們介紹第二種

@property (nonatomic,strong)MXSegmentedPager *segmentedPager;//!< MX架構




第一步(建立和準備)

用你的終端建立podfile檔案,在裡面寫上你需要的庫,然後就開搞了

platform:ios,‘7.0‘

target‘imageBlur‘do

pod‘MXSegmentedPager‘

pod‘SDWebImage‘

pod‘Masonry‘

end

既然準備的話就準備一個可以展開的頭部,來展示展開效果以及高斯模糊的效果


屬性拖出來以備後續操作



第二步(初始化架構MX)

我們展示三個控制器,按如下,分別給出幾個屬性


超級無敵詳細的備忘介紹如何初始化架構

// 初始化MX架構控制器,頭部和選擇欄- (void)initMX{    // 頭部    self.segmentedPager = [[MXSegmentedPager alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];    self.segmentedPager.parallaxHeader.view = self.headView; // 注意這裡載入平行頭部    // MXParallaxHeaderModeCenter MXParallaxHeaderModeCenter MXParallaxHeaderModeTop  MXParallaxHeaderModeBottom四個,大家可以自己測試    self.segmentedPager.parallaxHeader.mode = MXParallaxHeaderModeFill; // 平行頭部填充模式    self.segmentedPager.parallaxHeader.height = 240; // 頭部高度    self.segmentedPager.parallaxHeader.minimumHeight = 64; // 頭部最小高度        // 選擇欄控制器屬性    self.segmentedPager.segmentedControl.borderWidth = 1.0; // 邊框寬度    self.segmentedPager.segmentedControl.borderColor = [UIColor redColor]; // 邊框顏色    self.segmentedPager.segmentedControl.frame = CGRectMake(0, 0, self.view.bounds.size.width, 44); // frame    self.segmentedPager.segmentedControl.segmentEdgeInset = UIEdgeInsetsMake(0, 10, 0, 10);// 間距    self.segmentedPager.segmentedControl.selectionIndicatorHeight = 0;// 底部是否需要橫條指標,0的話就沒有了,    // 底部指標的寬度是否根據內容    self.segmentedPager.segmentedControl.selectionStyle = HMSegmentedControlSelectionStyleTextWidthStripe;    //HMSegmentedControlSelectionIndicatorLocationNone 不需要底部滑動指標    self.segmentedPager.segmentedControl.selectionIndicatorLocation = HMSegmentedControlSelectionIndicatorLocationNone;    self.segmentedPager.segmentedControl.verticalDividerEnabled = NO;// 不可以垂直滾動    // fix的枚舉說明寬度是適應螢幕的,不會根據字型   HMSegmentedControlSegmentWidthStyleDynamic則是字型多大就多寬    self.segmentedPager.segmentedControl.segmentWidthStyle = HMSegmentedControlSegmentWidthStyleFixed;        // 預設狀態的字型    self.segmentedPager.segmentedControl.titleTextAttributes =                            @{NSForegroundColorAttributeName : [UIColor colorWithRed:153/255.0 green:153/255.0 blue:153/255.0 alpha:1],                                         NSFontAttributeName : [UIFont systemFontOfSize:14]};    // 選擇狀態下的字型    self.segmentedPager.segmentedControl.selectedTitleTextAttributes =                                    @{NSForegroundColorAttributeName : [UIColor colorWithRed:255/255.0 green:174/255.0 blue:1 alpha:1],                                                 NSFontAttributeName : [UIFont systemFontOfSize:18]};    self.segmentedPager.segmentedControlEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);        self.segmentedPager.delegate = self;    self.segmentedPager.dataSource = self;    [self.view addSubview:self.segmentedPager];    [self.segmentedPager mas_makeConstraints:^(MASConstraintMaker *make)     {         make.top.equalTo(self.view.mas_top).with.offset(0);         make.left.equalTo(self.view.mas_left);         make.bottom.equalTo(self.view.mas_bottom);         make.right.equalTo(self.view.mas_right);         make.width.equalTo(self.view.mas_width);     }];}


第三步(代理方法)

最關鍵的代理方法實現,分別是頭部選擇欄的代理數組以及控制器的數組View,具體的控制器初始化可以在懶載入中

實現

#pragma -mark <MXSegmentedPagerDelegate>- (CGFloat)heightForSegmentedControlInSegmentedPager:(MXSegmentedPager *)segmentedPager{    // 指示欄的高度    return 44.0f;}#pragma -mark <MXSegmentedPagerDataSource>- (NSInteger)numberOfPagesInSegmentedPager:(MXSegmentedPager *)segmentedPager{    // 需要多少個介面    return 3;}- (NSString *)segmentedPager:(MXSegmentedPager *)segmentedPager titleForSectionAtIndex:(NSInteger)index{    // 指示欄的文字數組    return [@[@"控制器介面", @"WKWebView",@"雙TableView"] objectAtIndex:index];}- (UIView *)segmentedPager:(MXSegmentedPager *)segmentedPager viewForPageAtIndex:(NSInteger)index{    // 第一個是控制器的View 第二個是WebView  第三個是自訂的View 這個也是最關鍵的,通過懶載入把對應控制的初始化View載入到架構上面去    return [@[self.firstChildVC.view, self.webView, self.customView] objectAtIndex:index];}


第四步(導覽列消失)

我們在滾動的時候需要讓導覽列也跟著變換,那麼還有個代理方法需要實現

// 滾動整體的時候調用- (void)segmentedPager:(MXSegmentedPager *)segmentedPager didScrollWithParallaxHeader:(MXParallaxHeader *)parallaxHeader{    // 通過拿到滾動的對應的View    UIScrollView *scrollView = (UIScrollView *)segmentedPager.subviews[0];    NSLog(@"%lf",scrollView.contentOffset.y);    // 計算alpha值    CGFloat headAlpha = (1 - (-(scrollView.contentOffset.y + 64) / 136)) >= 0 ? (1 - (-(scrollView.contentOffset.y + 64) / 136)) : 0;    self.headView.alpha = 1 - headAlpha;    if (self.headView.alpha == 0)    {        self.navigationController.navigationBar.hidden = NO;    }    else    {        self.navigationController.navigationBar.hidden = YES;    }}



第五步(頭部圖片展開以及高斯模糊)

其實上面四個做完基本就差不多了,一個Demo就很簡單的了,那麼我們再加個頭部,展開玩玩,內建的平行頭部,

不玩白不玩

// 載入頭部模糊視圖的圖片和頭像- (void)initHeadView{    // 圓形頭像無需模糊    self.nickImageView.layer.cornerRadius = 25.0f;    self.nickImageView.clipsToBounds = YES;    self.nickImageView.layer.borderColor = [[UIColor whiteColor] CGColor];    self.nickImageView.layer.borderWidth = 2.0f;    __weak typeof(self)weakSelf = self;    [self.nickImageView sd_setImageWithURL:[NSURL URLWithString:@"http://twt.img.iwala.net/touxiang/563846208921b.jpg"]                          placeholderImage:nil                                 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {        if (image && cacheType == SDImageCacheTypeNone) {            [weakSelf.nickImageView setNeedsDisplay];            weakSelf.nickImageView.alpha = 0;            [UIView animateWithDuration:1.0 animations:^{                               weakSelf.nickImageView.alpha = 1.0f;            }];        }        else        {            weakSelf.nickImageView.alpha = 1.0f;        }    }];            // 背景做成模糊,方法已經在Demo裡面了,大家可以下載去取,一個方法暴露,簡單就能實現    [self.blurImageView sd_setImageWithURL:[NSURL URLWithString:@"http://twt.img.iwala.net/touxiang/563846208921b.jpg"]                          placeholderImage:nil                                 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {       [self.blurImageView setNeedsDisplay];                                             // 模糊開始        NSData *imageData = UIImageJPEGRepresentation(image, 0.5);        // 模糊介面,參數越接近1越模糊,直接調用他就OK了        UIImage *blurImage = [[UIImage imageWithData:imageData] blurredImage:0.15f];                                             weakSelf.blurImageView.image = blurImage;        if (image && cacheType == SDImageCacheTypeNone) {            weakSelf.blurImageView.alpha = 0;            [UIView animateWithDuration:1.0 animations:^{                               weakSelf.blurImageView.alpha = 1.0f;                            }];        }        else        {            weakSelf.blurImageView.alpha = 1.0f;        }            }];    [self.headView layoutSubviews];}

高斯的內部方法,可以拿去直接用

- (UIImage*)blurredImage:(CGFloat)blurAmount{    if (blurAmount < 0.0 || blurAmount > 1.0) {        blurAmount = 0.5;    }        int boxSize = (int)(blurAmount * 40);    boxSize = boxSize - (boxSize % 2) + 1;        CGImageRef img = self.CGImage;    vImage_Buffer inBuffer, outBuffer;    vImage_Error error;        void *pixelBuffer;        CGDataProviderRef inProvider = CGImageGetDataProvider(img);    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);        inBuffer.width = CGImageGetWidth(img);    inBuffer.height = CGImageGetHeight(img);    inBuffer.rowBytes = CGImageGetBytesPerRow(img);        inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);    pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));        outBuffer.data = pixelBuffer;    outBuffer.width = CGImageGetWidth(img);    outBuffer.height = CGImageGetHeight(img);    outBuffer.rowBytes = CGImageGetBytesPerRow(img);        error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);        if (!error) {        error = vImageBoxConvolve_ARGB8888(&outBuffer, &inBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);    }        if (error) {#ifdef DEBUG        NSLog(@"%s error: %zd", __PRETTY_FUNCTION__, error);#endif                return self;    }        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();        CGContextRef ctx = CGBitmapContextCreate(outBuffer.data,                                             outBuffer.width,                                             outBuffer.height,                                             8,                                             outBuffer.rowBytes,                                             colorSpace,                                             (CGBitmapInfo)kCGImageAlphaNoneSkipLast);        CGImageRef imageRef = CGBitmapContextCreateImage (ctx);        UIImage *returnImage = [UIImage imageWithCGImage:imageRef];        CGContextRelease(ctx);    CGColorSpaceRelease(colorSpace);        free(pixelBuffer);    CFRelease(inBitmapData);        CGImageRelease(imageRef);        return returnImage;}


用法就介紹到這裡,非常簡單,和TableView的用法差不多,初始化之後直接實現幾個


代理方法一樣,用起來十分習慣,至於內部的複用是如何?的這


裡就不多介紹了,各位有興趣的話可以看下源碼是如何進行複用的



我去,忘了介紹了。這裡還有個雙TableView的展示

我們首先要做的是自訂一個View繼承UIView

@interface MXCustomView () <MXPageProtocol, UITableViewDelegate, UITableViewDataSource>@property (nonatomic, strong) UITableView *table1;@property (nonatomic, strong) UITableView *table2;@end

兩個TableView的初始化以及代理方法就不展開了,可以看到Demo,主要介紹個方法,讓TableView是否能跟著整體

滾動與否

#pragma mark <MXPageProtocol>- (BOOL)segmentedPager:(MXSegmentedPager *)segmentedPager shouldScrollWithView:(UIView *)view {    // 返回NO就是代表是獨立的    if (view == self.table2) {        return NO;    }    // YES就是整體的    return YES;}


很好玩的東西竟然差點忘了






Demo地址:https://github.com/DeftMKJ/blur



OVER~~~~~~










iOS 網易新聞首頁進化版Demo(MXSegmentedPager),內建平行頭部展開

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.