iOS主流個(gè)人主頁(yè)隨滾動(dòng)可縮放頭圖

效果圖

  • 向上滾動(dòng)圖片變窄


    zoomHeaderImageView.gif
  • 向上滾動(dòng)圖片不變


    zoomHeaderImageViewNoNarrow.gif

源碼地址在我的github

前言

目前主流APP的個(gè)人主頁(yè)都會(huì)在頂部展示一個(gè)頭圖至耻,圖片可以由用戶自定義設(shè)置勋眯,不僅彰顯了用戶的個(gè)性野瘦,也增加了頁(yè)面的豐富性窄绒;并且頭圖也可以隨著頁(yè)面的滾動(dòng)有一種縮放的效果液样,大大的提高了用戶的交互性虾宇,讓用戶愛不釋手旨剥!如果你正在負(fù)責(zé)這方面的需求空扎,我覺得你應(yīng)該嘗試下這個(gè)效果。

實(shí)現(xiàn)原理

核心原理很簡(jiǎn)單赔嚎,就是UIViewcontentMode屬性膘盖。針對(duì)UIImageView有常用的三種mode:UIViewContentModeScaleToFill
UIViewContentModeScaleAspectFit尤误、UIViewContentModeScaleAspectFill,用三個(gè)圖片展示它們的區(qū)別吧侠畔。

  • UIViewContentModeScaleToFill 這個(gè)就比較暴力了,按著UIImageView的尺寸將圖片不按著原圖比例填滿损晤,所以出現(xiàn)了比較丑的壓扁效果软棺。
    UIViewContentModeScaleToFill.png
  • UIViewContentModeScaleToFill將圖片進(jìn)行等比例縮放,直到寬或者高和UIImageView的一樣尤勋。所以高度先合適喘落,寬度只能留白了。
    UIViewContentModeScaleAspectFit.png
  • UIViewContentModeScaleAspectFill將圖片進(jìn)行等比例縮放最冰,直到填滿整個(gè)UIImageView瘦棋,這個(gè)效果正是我們想要的。
    UIViewContentModeScaleAspectFill.png

綜上所述暖哨,我們將UIImageView.contentMode設(shè)置為UIViewContentModeScaleAspectFill赌朋,然后隨著滾動(dòng)的offsetY去更新UIImageView的y和height就行了。

代碼展示

我們開發(fā)的時(shí)候鹿蜀,對(duì)于視圖的布局一般有三種方式:

  • 直接設(shè)置視圖的frame箕慧,不進(jìn)行約束;

  • 使用代碼約束茴恰,常用的masonry颠焦;

  • 使用xib約束;
    選擇不同的布局方式往枣,在實(shí)現(xiàn)效果的細(xì)節(jié)上也是不一樣的伐庭,所以我針對(duì)這三種方式進(jìn)行分別展示粉渠。當(dāng)你的項(xiàng)目選擇一種適合的布局方式,然后選擇效果的實(shí)現(xiàn)方式即可圾另。

  • 直接設(shè)置視圖的frame霸株,不進(jìn)行約束

初始化視圖
- (void)initUINoConstraint
{
    UIImageView *headerImageView = [[UIImageView alloc] initWithFrame:self.bounds];
    headerImageView.clipsToBounds = YES;
    headerImageView.contentMode = UIViewContentModeScaleAspectFill;
    headerImageView.image = [UIImage imageNamed:@"lufei.jpg"];
    [self addSubview:headerImageView];
    self.headerImageView = headerImageView;
    self.originalHeaderImageViewFrame = self.bounds;
}
根據(jù)offsetY更新布局
- (void)updateHeaderImageViewFrameWithOffsetY:(CGFloat)offsetY
{
//防止height小于0
            if (self.originalHeaderImageViewFrame.size.height - offsetY < 0) {
                return;
            }
            //如果不使用約束的話,圖片的y值要上移offsetY,同時(shí)height也要增加offsetY
            CGFloat x = self.originalHeaderImageViewFrame.origin.x;
            CGFloat y = self.originalHeaderImageViewFrame.origin.y + offsetY;
            CGFloat width = self.originalHeaderImageViewFrame.size.width;
            CGFloat height = self.originalHeaderImageViewFrame.size.height - offsetY;
            self.headerImageView.frame = CGRectMake(x, y, width, height);
}
  • 使用代碼約束集乔,常用的masonry
初始化視圖
- (void)initUICodeConstraint
{
    UIImageView *headerImageView = [[UIImageView alloc] init];
    headerImageView.clipsToBounds = YES;
    headerImageView.contentMode = UIViewContentModeScaleAspectFill;
    headerImageView.image = [UIImage imageNamed:@"lufei.jpg"];
    [self addSubview:headerImageView];
    self.headerImageView = headerImageView;
    //約束設(shè)置為:跟父視圖左去件、下、右貼緊扰路,再約束高度尤溜,所以更新高度約束的時(shí)候會(huì)向上增加,xib約束同理
    [headerImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.and.bottom.equalTo(self).offset(0);
        self.codeConstraintHeight = make.height.equalTo(@(self.bounds.size.height));
    }];
    self.originalHeaderImageViewHeight = self.bounds.size.height;
}
根據(jù)offsetY更新布局
- (void)updateHeaderImageViewFrameWithOffsetY:(CGFloat)offsetY
{
//防止height小于0
            if (self.originalHeaderImageViewHeight -offsetY < 0) {
                return;
            }
            //第一種方式:獲取到這個(gè)約束汗唱,直接對(duì)約束值修改
            //self.codeConstraintHeight.equalTo(@(self.originalHeaderImageViewHeight -offsetY));
            //第二種方式:直接使用masonry提供的更新約束方法宫莱,其實(shí)原理是一樣的
            [self.headerImageView mas_updateConstraints:^(MASConstraintMaker *make) {
                make.height.equalTo(@(self.originalHeaderImageViewHeight -offsetY));
            }];
}
  • 使用xib約束
//需要將xib中的高度約束用拉線拉出來
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *layoutHeightOfHeaderImageView;
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        self.isNeedNarrow = YES;
        [self initUIXibConstraint];
    }
    return self;
}
根據(jù)offsetY更新布局
- (void)updateHeaderImageViewFrameWithOffsetY:(CGFloat)offsetY
{
//防止height小于0
            if (self.originalHeaderImageViewHeight -offsetY < 0) {
                return;
            }
            self.layoutHeightOfHeaderImageView.constant = self.originalHeaderImageViewHeight - offsetY;
}
  • 向上滾動(dòng)圖片是否變窄的實(shí)現(xiàn)
//用于實(shí)現(xiàn)向上滾動(dòng)的時(shí)候,圖片不變窄
- (void)updateHeaderImageViewFrameWithOffsetY:(CGFloat)offsetY
{
    if (!self.isNeedNarrow && offsetY > 0) {
        return;
    }
}

外部使用

    //沒有約束
//    ZoomHeaderView *headerView = [[ZoomHeaderView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 300) type:ZoomHeaderViewTypeNoConstraint];
    //代碼約束
//    ZoomHeaderView *headerView = [[ZoomHeaderView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 300) type:ZoomHeaderViewTypeCodeConstraint];
    //xib約束
    ZoomHeaderView *headerView = [[[NSBundle mainBundle] loadNibNamed:@"ZoomHeaderView" owner:nil options:nil] lastObject];
    //可以對(duì)比看效果
//    headerView.isNeedNarrow = NO;
    tableView.tableHeaderView = headerView;
    self.headerView = headerView;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat offsetY = scrollView.contentOffset.y;
    [self.headerView updateHeaderImageViewFrameWithOffsetY:offsetY];
}

總結(jié)

總得來說哩罪,代碼還是比較簡(jiǎn)單的授霸,可以快捷實(shí)現(xiàn)滾動(dòng)縮放的效果,只是要注意一些細(xì)節(jié)設(shè)置际插,歡迎大家去我的github,下載源碼進(jìn)行查看碘耳。如何我的描述中有什么紕漏或者錯(cuò)誤的地方,麻煩各位大神多多指正框弛!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末藏畅,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子功咒,更是在濱河造成了極大的恐慌,老刑警劉巖绞蹦,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件力奋,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡幽七,警方通過查閱死者的電腦和手機(jī)景殷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來澡屡,“玉大人猿挚,你說我怎么就攤上這事∈火模” “怎么了绩蜻?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)室埋。 經(jīng)常有香客問我办绝,道長(zhǎng)伊约,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任孕蝉,我火速辦了婚禮屡律,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘降淮。我一直安慰自己超埋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布佳鳖。 她就那樣靜靜地躺著霍殴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腋颠。 梳的紋絲不亂的頭發(fā)上繁成,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音淑玫,去河邊找鬼巾腕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛絮蒿,可吹牛的內(nèi)容都是我干的尊搬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼土涝,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼佛寿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起但壮,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤冀泻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蜡饵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弹渔,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年溯祸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肢专。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡焦辅,死狀恐怖博杖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情筷登,我是刑警寧澤剃根,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站前方,受9級(jí)特大地震影響跟继,放射性物質(zhì)發(fā)生泄漏种冬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一舔糖、第九天 我趴在偏房一處隱蔽的房頂上張望娱两。 院中可真熱鬧,春花似錦金吗、人聲如沸十兢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)旱物。三九已至,卻和暖如春卫袒,著一層夾襖步出監(jiān)牢的瞬間宵呛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工夕凝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宝穗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓码秉,卻偏偏與公主長(zhǎng)得像逮矛,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子转砖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • -- iOS事件全面解析 概覽 iPhone的成功很大一部分得益于它多點(diǎn)觸摸的強(qiáng)大功能糖荒,喬布斯讓人們認(rèn)識(shí)到手機(jī)其實(shí)...
    翹楚iOS9閱讀 2,966評(píng)論 0 13
  • 每天讀一遍,連續(xù)21天模捂,你將獲得宇宙無限的正能量 從今天開始的每一天 我已經(jīng)改變成為一個(gè)全新的人 我充滿了靈性和愛...
    龔嘉淇閱讀 425評(píng)論 0 0
  • 修改配置文件:-Xms512m-Xmx2048m-XX:MaxPermSize=768-XX:ReservedCo...
    goodl閱讀 271評(píng)論 0 1
  • 從今兒開始記錄我的營(yíng)養(yǎng)早餐, 今兒心情很美麗蜘矢,只因有陽(yáng)光狂男。 化個(gè)妝,即便不出門也要美美噠品腹! 女為悅己者容岖食,是一種順...
    朱莉葉6666閱讀 232評(píng)論 0 0
  • 你的自制力如何?哈哈舞吭,有沒有對(duì)生活有些規(guī)劃泡垃,有沒有經(jīng)常拖沓析珊,有沒有生活目標(biāo)和實(shí)現(xiàn)的愿望,有沒有很想去的遠(yuǎn)方蔑穴,有沒有...
    蘑菇樂閱讀 688評(píng)論 0 0