iOS 練習項目 Landmarks (四):添加 AutoLayout 約束

iOS 練習項目 Landmarks (四):添加 AutoLayout 約束

  • iOS 練習項目 Landmarks (四):添加 AutoLayout 約束
    • 新增 topLabel
    • 圖片視圖圓形裁切+陰影
    • 使用 AutoLayout 為詳情頁的組件添加約束
    • DetailViewControllerDelegate
    • 為 PlaceCell 添加 AutoLayout 約束

iOS 練習項目 Landmarks (四):添加 AutoLayout 約束

新增 topLabel

與參考視頻對比,返回標簽的右邊還要有一個顯示景點名的標題,在詳情頁新增一個居中的 UILabel 來顯示,命名為 topLabel。

圖片視圖圓形裁切+陰影

要使得圖片展示為一個圓形,先設置一個正方形的 pictureView,再設置它的 layer.cornerRadius 為邊長的一半,masksToBounds 是 layer 的屬性,含義是子視圖是否裁剪圖層邊界,設置為 YES 后,imageView 超出半徑的部分就被裁減掉,這樣就剩下一個圓形。

在圓形外設置一個 4px 的白色 border,就完成了邊界的設置。

然后設置邊界外的陰影,通過設置 layer.shadowOffset、layer.shadowRedius、layer.shadowPath、layer.shadowColor、layer.shadowOpacity 等屬性,但是沒有效果,因為 masksToBounds = true 會把設置的陰影裁剪掉。一種添加陰影的方法是在 pictureView 外套一層 shadowView,shadowView 的 frame 大小和 pictureView 相同,在 shadowView 上設置陰影效果,再讓 picture View 作為 shadowView 的子視圖。

    CGRect pictureFrame = CGRectMake(0, 0, 250, 250);// 創建并設置 pictureViewself.pictureView = [[UIImageView alloc] initWithFrame:pictureFrame];[self.pictureView setImage:[self.place picture]];self.pictureView.layer.cornerRadius = 125.0;self.pictureView.layer.borderWidth = 4.0;self.pictureView.layer.borderColor = [UIColor whiteColor].CGColor;// self.pictureView.contentMode = UIViewContentModeScaleAspectFit;self.pictureView.translatesAutoresizingMaskIntoConstraints = NO;// 在 pictureView 上直接設置陰影,會因為 masksToBounds = true 而被裁減掉self.pictureView.layer.masksToBounds = YES;// 在 pictureView 外套一層 shadowViewUIView *shadowView = [[UIView alloc] initWithFrame:self.pictureView.frame];shadowView.layer.shadowColor = [UIColor grayColor].CGColor;shadowView.layer.shadowOffset = CGSizeMake(0, 0);shadowView.layer.shadowOpacity = 1;shadowView.layer.shadowRadius = 9.0;shadowView.layer.cornerRadius = 9.0;[shadowView addSubview:self.pictureView];...[self.view addSubview:shadowView];
  • clipToBounds 是 view 的屬性,含義是子視圖只展示父視圖邊界內的內容,邊界外會被裁減掉,默認為 NO。
  • masksToBounds 是 layer 的屬性,含義是子視圖是否裁剪圖層邊界,默認為 NO。

使用 AutoLayout 為詳情頁的組件添加約束

UIView 有一個屬性:translatesAutoresizingMaskIntoConstraints,字面意思是把 autoresizingMask 轉換為 Constraints,實際意思是把 frame ,bouds,center 方式布局的視圖自動轉化為約束形式,此時該視圖上約束已經足夠,不需要手動去添加別的約束。

  • 用代碼創建的所有view , translatesAutoresizingMaskIntoConstraints 默認是 YES
  • 用 IB 創建的所有 view ,translatesAutoresizingMaskIntoConstraints 默認是 NO(autoresize 布局為 YES , autolayout 布局為 NO)。

如果我們要給視圖添加自己創建的約束,會和上述約束沖突,所以使用 AutoLayout 前需要將視圖的 translatesAutoresizingMaskIntoConstraints 屬性設置為 NO。

接下來就是添加約束了:

		/* 添加約束 */// topLabel 的上邊緣距離 view 的上邊緣有 50px,且居中顯示[NSLayoutConstraint activateConstraints:@[[self.topLabel.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:50],[self.topLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor], // 設置視圖位于 X 軸居中[self.topLabel.heightAnchor constraintEqualToConstant:50] // 設置視圖的高度為 50 點]];// mapView 的上邊緣位于 topLabel 的下邊緣NSLayoutConstraint *mapTopAttachToTopButtom = [NSLayoutConstraint constraintWithItem:self.mapView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.topLabel attribute:NSLayoutAttributeBottom multiplier:1 constant:0];[self.view addConstraint:mapTopAttachToTopButtom];[NSLayoutConstraint activateConstraints:@[[self.mapView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor], // 設置地圖視圖位于 X 軸居中// [self.mapView.topAnchor constraintEqualToAnchor:self.topLabel.bottomAnchor],// [self.mapView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],// [self.mapView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],[self.mapView.widthAnchor constraintEqualToAnchor:self.view.widthAnchor],[self.mapView.heightAnchor constraintEqualToConstant:290] // 設置地圖視圖的高度為 290px]];// pictureView 的中心位于 mapView 的下邊緣NSLayoutConstraint *pictureCenterYAttachToMapButtom = [NSLayoutConstraint constraintWithItem:self.pictureView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.mapView attribute:NSLayoutAttributeBottom multiplier:1 constant:0];[self.view addConstraint:pictureCenterYAttachToMapButtom];// pictureView 的寬高為 250px,且 X 軸居中[NSLayoutConstraint activateConstraints:@[[self.pictureView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor], // 設置圖片視圖位于 X 軸居中// [self.pictureView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor], // 設置圖片視圖位于 Y 軸居中[self.pictureView.widthAnchor constraintEqualToConstant:250], // 設置圖片視圖的寬度為 250px[self.pictureView.heightAnchor constraintEqualToConstant:250] // 設置圖片視圖的高度為 250px]];// sightLabel 位于 pictureView 下方 30px 處,距離屏幕左邊界 20px[NSLayoutConstraint activateConstraints:@[[self.sightLabel.topAnchor constraintEqualToAnchor:self.pictureView.bottomAnchor constant:30],[self.sightLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20],[self.sightLabel.heightAnchor constraintEqualToConstant:80]]];// starButton 位于 sightLabel 右側,距離 4px[NSLayoutConstraint activateConstraints:@[[self.starButton.leadingAnchor constraintEqualToAnchor:self.sightLabel.trailingAnchor constant:4],[self.starButton.topAnchor constraintEqualToAnchor:self.sightLabel.topAnchor],[self.starButton.bottomAnchor constraintEqualToAnchor:self.sightLabel.bottomAnchor],[self.starButton.widthAnchor constraintEqualToConstant:25],[self.starButton.heightAnchor constraintEqualToConstant:25]]];// scenicAreaLabel 位于 sightLabel 下方,距離 15px[NSLayoutConstraint activateConstraints:@[[self.scenicAreaLabel.topAnchor constraintEqualToAnchor:self.sightLabel.bottomAnchor constant:15],[self.scenicAreaLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20],[self.scenicAreaLabel.heightAnchor constraintEqualToConstant:20]]];// stateLabel 與 scenicAreaLabel 水平,其右邊界距離屏幕右邊界 20px[NSLayoutConstraint activateConstraints:@[[self.stateLabel.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-20],[self.stateLabel.topAnchor constraintEqualToAnchor:self.scenicAreaLabel.topAnchor],[self.stateLabel.bottomAnchor constraintEqualToAnchor:self.scenicAreaLabel.bottomAnchor],[self.stateLabel.heightAnchor constraintEqualToConstant:20]]];

DetailViewControllerDelegate

詳情頁的 starButton 也要能修改數據源,所以在 DetailViewController 里聲明一個 DetailViewControllerDelegate 協議。

@protocol DetailViewControllerDelegate <NSObject>@optional- (void)detailViewController:(DetailViewController *)detailViewController goBackWithFavorite:(BOOL)favorite atIndex:(NSInteger)index;@end@interface DetailViewController : UIViewController@property (nonatomic, weak) id <DetailViewControllerDelegate> detailViewControllerDelegate;...@end

里面有一個可選方法,作用是將 favorite 從詳情頁傳回主頁,根據 index 修改數據源對應下標的 Place 對象的 favorite 屬性。

在 ViewController 引入這個協議,在 tableView:didSelectRowAtIndexPath: 方法中,我們創建了 DetailViewController 對象,之后要設置代理,別忘了設置 index 屬性:

// 設置代理,并且遵守 DetailViewControllerDelegate
detailViewController.detailViewControllerDelegate = self;
// 別忘了設置 index 屬性
[detailViewController setIndex:indexPath.row];

并且實現協議的方法:

# pragma mark - DtailViewControllerDelegate Method- (void)detailViewController:(DetailViewController *)detailViewController goBackWithFavorite:(BOOL)favorite atIndex:(NSInteger)index
{// 修改數據源對應的對象[self.places[index] setFavorite:favorite];// TableView 重新加載被修改了的那一行[placeTable reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationNone];// [self.placeTable reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}

為詳情頁的starButton的點擊事件添加一個目標-動作對,點擊按鈕,將starButton.selected保存到favorite,再通知代理執行協議方法:

- (void)starButtonClicked:(UIButton *)sender
{sender.selected = !sender.selected;// [place setFavorite:sender.selected];self.favorite = sender.selected;// 首先判斷代理人是否存在并且是否遵守協議并且實現了協議方法if (_detailViewControllerDelegate && [_detailViewControllerDelegate respondsToSelector:@selector(detailViewController:goBackWithFavorite:atIndex:)]){// 如果滿足判斷條件,則讓代理執行協議方法,此處讓代理人執行協議方法,在代理人那個控制器中的協議方法會被執行[_detailViewControllerDelegate detailViewController:self goBackWithFavorite:self.favorite atIndex:self.index];}
}

為 PlaceCell 添加 AutoLayout 約束

之前提到過:在自己實現的PlaceCell中,目前只有imageView的上面空出了10px,其實下面也要空出距離,實現imageView和contentView的上下都有空位的效果。現在通過 AutoLayout 約束,使得 imageView 的上下分別距離 contentView 5px,就可以實現這個效果,再設置 textLabel 和 starButton 位于 contentView 的 Y 軸居中。

    // 添加約束[NSLayoutConstraint activateConstraints:@[[self.imageView.widthAnchor constraintEqualToConstant:50],[self.imageView.heightAnchor constraintEqualToConstant:50],[self.imageView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:20],[self.imageView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:5],[self.imageView.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-5],[self.textLabel.centerYAnchor constraintEqualToAnchor:self.contentView.centerYAnchor],[self.textLabel.leadingAnchor constraintEqualToAnchor:self.imageView.trailingAnchor constant:10],[self.starButton.centerYAnchor constraintEqualToAnchor:self.contentView.centerYAnchor], // 設置圖片視圖位于 Y 軸居中[self.starButton.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-10],[self.starButton.widthAnchor constraintEqualToConstant:25],[self.starButton.heightAnchor constraintEqualToConstant:25]]];

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/37917.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37917.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37917.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何在 Logback 和 Log4j 中獲取日志:一個開發者指南

日志記錄是軟件開發中的關鍵實踐&#xff0c;它幫助我們監控應用程序的行為&#xff0c;定位問題并優化性能。在 Java 生態系統中&#xff0c;Logback 和 Log4j 是兩個廣泛使用的日志框架&#xff0c;它們都基于 SLF4J API 提供日志服務。本文將指導你如何在這兩個框架中獲取日…

7-490 將字符串“software“賦給一個字符指針,并從第一個字母開始間隔地輸出該串(簡單字符串)

編程將字符串"software"賦給一個字符指針 然后從第一個字母開始間隔地輸出該串 請用指針法完成。 輸入樣例: 在這里給出一組輸入。例如&#xff1a; 無輸入輸出樣例: 在這里給出相應的輸出。例如&#xff1a; sfwr #include <stdio.h> #include <stri…

Linux環境下快速部署Spring Boot應用:高效命令組合實踐

概要&#xff1a; 本文旨在介紹一種高效的Linux命令組合&#xff0c;用于簡化Spring Boot項目的部署與管理流程。通過結合使用nohup、java -jar、輸出重定向以及進程管理命令&#xff0c;我們能夠實現Spring Boot應用的快速后臺啟動及便捷的進程控制&#xff0c;尤其適合于自動…

什么是 JVM( Java 虛擬機),它在 Java 程序執行中扮演什么角色?

JVM&#xff0c;全稱Java Virtual Machine&#xff0c;中文譯作“Java虛擬機”&#xff0c;它是運行Java程序的軟件環境&#xff0c;也是Java語言的核心部分之一。 想象一下&#xff0c;如果你是一位環球旅行家&#xff0c;每到一個新的國家&#xff0c;都需要學習當地的語言才…

【Linux】初識操作系統

一、馮?諾依曼體系結構 在學習操作系統之前&#xff0c;我們先來認識一下馮?諾依曼體系結構&#xff0c;我們常見的計算機&#xff0c;如筆記本。我們不常見的計算機&#xff0c;如服務器&#xff0c;大部分都遵守馮諾依曼體系。 截至目前&#xff0c;我們所認識的計算機&am…

神經網絡訓練(一):基于殘差連接的圖片分類網絡(ResNet18)

目錄 一、簡介:二、圖片分類網絡1.記載訓練數據(torch自帶的cifa10數據集)2.數據增強3.模型構建4.模型訓練三、完整源碼及文檔一、簡介: 基于殘差連接的圖片分類網絡,本網絡使用ResNet18作為基礎模塊,根據cifa10的特點進行改進網絡,使用交叉熵損失函數和SGD優化器。本網…

使用pyqt5編寫一個七彩時鐘

使用pyqt5編寫一個七彩時鐘 效果代碼解析定義 RainbowClockWindow 類初始化用戶界面顯示時間方法 完整代碼 在這篇博客中&#xff0c;我們將使用 PyQt5 創建一個簡單的七彩數字時鐘。 效果 代碼解析 定義 RainbowClockWindow 類 class RainbowClockWindow(QMainWindow):def _…

【TB作品】溫濕度監控系統設計,ATMEGA16單片機,Proteus仿真

題2:溫濕度監控系統設計 功能要求: 1)開機顯示時間(小時、分)、時分可修改; 2)用兩個滑動變阻器分別模擬溫度傳感器(測量范 圍0-100度)與濕度傳感器(0-100%),通過按鍵 可以在數碼管切換顯示當前溫度值、濕度值; 3)當溫度低于20度時,紅燈長亮; 4)當濕度高于70%時,黃燈長亮; 5)當…

安卓實現微信聊天氣泡

一搜沒一個能用的&#xff0c;我來&#xff1a; 布局文件&#xff1a; <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xml…

Tech Talk:智能電視eMMC存儲的五問五答

智能電視作為搭載操作系統的綜合影音載體&#xff0c;以穩步擴大的市場規模走入越來越多的家庭&#xff0c;成為人們生活娛樂的重要組成部分。存儲部件是智能電視不可或缺的組成部分&#xff0c;用于保存操作系統、應用程序、多媒體文件和用戶數據等信息。智能電視使用eMMC作為…

vue3中使用Antv G6渲染樹形結構并支持節點增刪改

寫在前面 在一些管理系統中&#xff0c;會對組織架構、級聯數據等做一些管理&#xff0c;你會怎么實現呢&#xff1f;在經過調研很多插件之后決定使用 Antv G6 實現&#xff0c;文檔也比較清晰&#xff0c;看看怎么實現吧&#xff0c;先來看看效果圖。點擊在線體驗 實現的功能…

服務端開發過程中常見的安全性問題

身份驗證與授權 密碼加密 加密傳輸 Https DDoS SQL注入 SQL注入的本質:數據和代碼未分離&#xff0c;即數據當做了代碼來執行。 解決辦法 檢查輸入的數據是否符合預期&#xff0c;不能直接放入數據庫中進行查詢字符串長度驗證mybatis具有防sql注入的方式 使用#{}代替${…

深入探討光刻技術:半導體制造的關鍵工藝

前言 光刻&#xff08;Photolithography&#xff09;是現代半導體制造過程中不可或缺的一環&#xff0c;它的精度和能力直接決定了芯片的性能和密度。本文將詳細介紹光刻技術的基本原理、過程、關鍵技術及其在半導體制造中的重要性。 光刻技術的基本原理 光刻是一種利用光化…

受限玻爾茲曼機淺析

受限玻爾茲曼機&#xff08;Restricted Boltzmann Machine&#xff0c;簡稱RBM&#xff09;是一種特殊的隨機生成神經網絡&#xff0c;能夠學習并發現數據的復雜規則分布。以下是關于受限玻爾茲曼機算法的詳細介紹&#xff1a; ?? 定義與起源 定義&#xff1a; 受限玻爾茲…

深入剖析Tomcat(十四) Server、Service 組件:如何啟停Tomcat服務?

通過前面文章的學習&#xff0c;我們已經了解了連接器&#xff0c;四大容器是如何配合工作的&#xff0c;在源碼中提供的示例也都是“一個連接器”“一個頂層容器”的結構。并且啟動方式是分別啟動連接器和容器&#xff0c;類似下面代碼 connector.setContainer(engine); try …

主流分布式消息中間件RabbitMQ、RocketMQ

分布式消息中間件在現代分布式系統中起著至關重要的作用。以下是一些主流的分布式消息中間件&#xff1a; 1. Apache Kafka - 特點&#xff1a;高吞吐量、低延遲、持久化、水平可擴展、分布式日志系統。 - 使用場景&#xff1a;日志收集與處理、實時流處理、事件驅動架構、大數…

NC204871 求和

鏈接 思路&#xff1a; 對于一個子樹來說&#xff0c;子樹的節點就包括在整顆樹的dfs序中子樹根節點出現的前后之間&#xff0c;所以我們先進行一次dfs&#xff0c;用b數組的0表示區間左端點&#xff0c;1表示區間右端點&#xff0c;同時用a數組來標記dfs序中的值。處理完dfs序…

小程序的運行機制、更新機制、生命周期介紹保姆級教程全解

一、小程序運行機制 1. 小程序冷啟動 小程序啟動可以分為兩種情況&#xff0c;一種是冷啟動&#xff0c;一種是熱啟動- 冷啟動&#xff1a;如果用戶首次打開&#xff0c;或小程序銷毀后被用戶再次打開&#xff0c;此時小程序需要重新加載啟動- 熱啟動&#xff1a;如果用戶已經打…

HSP_12章 Python面向對象編程oop_多態

文章目錄 P128 多態問題的引出P129 多態細節和使用1. 多態介紹&特別說明2. 多態的好處3. 特別說明: Python多態的特點4. 使用多態的機制來解決主人喂食物的問題 P128 多態問題的引出 先看一個問題 # 說明: 先試用傳統的方式完成 class Food:name Nonedef __init__(self,…

4.Android逆向協議-詳解二次打包失敗解決方案

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 內容參考于&#xff1a;微塵網校 上一個內容&#xff1a;3.Android逆向協議-APP反反編譯及回編譯 工具下載&#xff1a; 鏈接&#xff1a;https://pan.baidu.…