UI學習--導航控制器

導航控制器

  • 導航控制器基礎
    • 基本概念
    • 具體使用
  • 導航控制器切換
    • 演示
    • 具體使用
    • 注意
  • 導航欄與工具欄
    • 基本概念
    • 具體使用:
  • 總結


導航控制器基礎

基本概念

  • 根視圖控制器(Root View Controller):導航控制器的第一個視圖控制器,通常是應用程序的主屏幕。
  • 導航欄(Navigation Bar):用于顯示當前視圖控制器的標題以及在導航棧中的位置。
  • 工具欄(Toolbar):可選的,用于顯示當前視圖控制器的工具按鈕。
  • 返回按鈕(BackButton):用于在導航欄中返回上一個視圖控制器。

下圖是一個導航欄的組成。
在這里插入圖片描述

具體使用

首先我們要創建一個根視圖控制器,該類繼承UIViewController。
在這里插入圖片描述
然后我們在SceneDelegate.m中我們創建一個根視圖控制器對象和導航控制器對象。


#import "SceneDelegate.h"
#import "VCRoot.h"
@interface SceneDelegate ()@end@implementation SceneDelegate- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {self.window.frame = [UIScreen mainScreen].bounds;//創建一個根視圖控制器VCRoot *root = [[VCRoot alloc] init];//創建導航控制器//導航控制器主要用來管理多個視圖控制器的切換//層級的方式來管理多個視圖控制器//創建控制器時,一定要有一個根視圖控制器UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController: root];root.view.backgroundColor = [UIColor blueColor];//將windows的根視圖設置為導航控制器self.window.rootViewController = nav;[self.window makeKeyAndVisible];
}

隨后,我們在我們創建的根視圖控制器的實現接口中,完成對導航欄屬性的學習。

  • UIBarButtonItem:是 iOS 中用于創建和管理導航欄、工具欄等界面元素的類。
    該類有三種初始化方法,一個是自定義文本,一個是使用系統風格,一個是將其他類型的控件作為按鈕。
  • self.title = @"根視圖"與 self.navigationItem.title = @"Title";:這兩個都是設置導航欄標題的屬性,navigationItem.title的優先級高于title

#import "VCRoot.h"
@interface VCRoot ()@end@implementation VCRoot- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.self.view.backgroundColor = [UIColor yellowColor];//設置導航欄的標題文字self.title = @"根視圖";//上下都是設置title//如果沒有設置navigationItem.title,為nil,//系統則會使用self。title作為標題。//優先下,再看上,如無下,則將上賦值給下//設置導航元素項目的標題self.navigationItem.title = @"Title";//創建一個導航欄左側的按鈕//根據title文字來創建按鈕//P1:按鈕上的文字//P2:按鈕風格//P3:事件擁有者//P4:按鈕事件//Bar專門用在導航欄上的按鈕UIBarButtonItem *leftBtn = [[UIBarButtonItem alloc] initWithTitle:@"左側" style:UIBarButtonItemStyleDone target:self action:@selector(pressLeft)];//導航元素項的左側按鈕賦值self.navigationItem.leftBarButtonItem = leftBtn;//創建一個導航欄左側的按鈕//根據系統風格創建按鈕//P1:按鈕上的文字//P2:按鈕風格//P3:事件擁有者//只需要指定風格樣式,系統風格的按鈕內容或標題文字不能改變UIBarButtonItem *rightBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(pressRight)];UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 50, 40)] ;label.text = @"test";label.textAlignment = NSTextAlignmentCenter;//將任何類型的控件添加到導航按鈕的方法UIBarButtonItem *item3 = [[UIBarButtonItem alloc] initWithCustomView:label] ;//添加多個按鈕,創建按鈕數組NSArray *arrayBtn = [NSArray arrayWithObjects:rightBtn,item3, nil ];UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(press:)];[label addGestureRecognizer:tap];label.userInteractionEnabled = YES;self.navigationItem.rightBarButtonItems = arrayBtn;
}-(void)press: (UITapGestureRecognizer*)tap {NSLog(@"press");
}
-(void) pressLeft
{NSLog(@"左側按鈕被按下!");
}-(void) pressRight
{NSLog(@"右側按鈕被按下!");
}@end

效果:
在這里插入圖片描述

導航控制器切換

演示

下圖為通過點擊切換了不同的視圖,而我們通過導航控制器也可以實現這一需求。
在這里插入圖片描述

具體使用

首先我們創建三個視圖控制器。
在這里插入圖片描述
然后,與上面所學相同,我們需要在SceneDelegate.m中我們創建一個根視圖控制器對象和導航控制器對象。


#import "SceneDelegate.h"
#import "VCRoot.h"
@interface SceneDelegate ()@end@implementation SceneDelegate- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {self.window.frame = [UIScreen mainScreen].bounds;VCRoot *root = [[VCRoot alloc] init];UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:root];self.window.rootViewController = nav;[self.window makeKeyAndVisible];}

接著,我們在根視圖中使用導航欄進行下一級視圖控制器的推出。
首先學習translucent屬性,該屬性用于控制視圖控制器是否透明,默認為YES,透明的。
不透明效果:
在這里插入圖片描述
我們通過創建一個按鈕,在響應事件中添加pushViewController: animated:方法,來實現下一個視圖的推出。注意,需要新建下一級視圖控制器


#import "VCRoot.h"
#import "VCSecond.h"
@interface VCRoot ()@end@implementation VCRoot- (void)viewDidLoad {[super viewDidLoad];//設置導航欄的透明度//默認透明度為YES,可透明的。//NO為不透明。self.navigationController.navigationBar.translucent = YES;self.navigationController.navigationBar.barStyle = UIBarStyleDefault;self.view.backgroundColor = [UIColor whiteColor];self.title = @"根視圖";UIBarButtonItem *next = [[UIBarButtonItem alloc] initWithTitle:@"下一級" style:UIBarButtonItemStylePlain target:self action:@selector(pressNext)];self.navigationItem.rightBarButtonItem = next;
}-(void) pressNext
{//創建新的視圖控制器VCSecond* vcSecond = [[VCSecond alloc] init];//使用當前視圖控制器的導航控制器對象,推出vcSecond控制器//參二為是否需要添加動畫效果[self.navigationController pushViewController:vcSecond animated:YES];
}@end

同樣的,我們在二級視圖中用相同的方法推出第三級視圖


#import "VCSecond.h"
#import "VCThired.h"
@interface VCSecond ()@end@implementation VCSecond- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor greenColor];self.title = @"兒子視圖";UIBarButtonItem *btnNext = [[UIBarButtonItem alloc] initWithTitle:@"第三級" style:UIBarButtonItemStylePlain target:self action:@selector(pressNext)];self.navigationItem.rightBarButtonItem = btnNext;
}-(void) pressNext
{VCThired *vc = [[VCThired alloc] init];[self.navigationController pushViewController:vc animated:YES];
}

我們在第三級中,自己設定左側按鈕,此時會發現自己設定的按鈕樣式會覆蓋系統的按鈕樣式。
當迭代到第三級后,我們想直接返回到根視圖時,可以使用popToRootViewControllerAnimated方法作為響應事件,直接返回到根視圖。


#import "VCThired.h"@interface VCThired ()@end@implementation VCThired- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.self.title = @"孫子視圖";UIBarButtonItem *btnLeft = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(pressBack)];UIBarButtonItem *btnRight = [[UIBarButtonItem alloc] initWithTitle:@"返回根視圖" style:UIBarButtonItemStylePlain target:self action:@selector(pressRight)];//當自己設定左側按鈕時//返回按鈕會被左側按鈕替換self.navigationItem.leftBarButtonItem = btnLeft;self.view.backgroundColor = [UIColor blueColor];self.navigationItem.rightBarButtonItem = btnRight;
}-(void) pressRight
{[self.navigationController popToRootViewControllerAnimated:YES];
}-(void) pressBack
{//將當前的視圖控制器彈出,返回上一級界面[self.navigationController popViewControllerAnimated:YES];
}@end

效果展示:
在這里插入圖片描述

注意

在每一個視圖中,我們進行視圖的推出和返回時,都對self.navigationController對象進行。那這個self.navigationController對象是不同的三個對象呢,還是同一個對象?

實際上,三個不同視圖中的self.navigationController對象都是同一個對象。
這與導航控制器推出視圖控制器的方式有關:通過 [self.navigationController pushViewController:vc animated:YES] 方法將視圖控制器 vc 推入導航堆棧時,vc 成為導航堆棧的最頂層視圖控制器,但導航控制器對象本身并沒有改變。
因此:我們每次看到的視圖就是導航堆棧的棧頂,使用push是將視圖控制器推入棧頂,使用pop是將視圖控制器推出棧頂。
而因為導航控制器對象本身是沒有改變的,所以我們設置了根視圖的導航控制器,就設置了所有視圖的導航控制器


導航欄與工具欄

基本概念

導航欄前面已經介紹了,我們在此著重介紹工具欄。
工具欄的組件:

  1. 固定空間按鈕(Fixed Space Bar Button):固定空間按鈕是另一種特殊類型的工具欄按鈕,用于創建固定寬度的間距。它可以用于調整按鈕之間的間距或在工具欄上創建對齊效果。
  2. 標簽(Label):用于顯示相關的信息或標題,提供上下文或描述工具欄中的操作。
  3. 圖片視圖(Image View):用于顯示圖標、圖像或其他視覺元素。圖像視圖可以代表特定的操作或提供視覺上的識別。
  4. 自定義視圖(Custom View):自定義的視圖元素,自定義視圖可以是任何 UIView 的子類,允許你在工具欄上添加自定義的界面元素,如文本輸入框、開關按鈕等。

工具欄的基本元素:

  1. 工具欄按鈕(Toolbar Button):工具欄中的單個按鈕,可以通過點擊來執行特定操作或導航到其他屏幕。
  2. 工具欄項(ToolbarItem):工具欄中的一個單獨元素,可以包含一個或多個工具欄按鈕。
  3. 工具欄控制器(ToolbarController):用于管理工具欄的視圖控制器,可以使用工具欄控制器來添加、刪除和重新排列工具欄項。
  4. 工具欄樣式(ToolbarStyle):工具欄的外觀樣式,可以通過設置工具欄的顏色、透明度、背景圖像和按鈕樣式等屬性來自定義工具欄的外觀。

具體使用:

導航欄的創建在此不再贅述,我們直接進入學習
隱藏導航欄的兩個方法:

	//該屬性默認為NOself.navigationController.navigationBar.hidden = NO;self.navigationController.navigationBarHidden = NO;

在iOS13之后,我們使用UIBarAppearance類設置導航控制器的外觀樣式

    //UIBarAppearance是iOS13后推出的一個對相應空間設置外觀樣式的類,可以統一配置NavigationBar、TabBar、ToolBar等的外觀樣式//UINavigationBarAppearance可以設置導航欄對象的外觀樣式//創建一個UINavigationBarAppearance對象UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];//背景顏色appearance.backgroundColor = [UIColor whiteColor];//陰影appearance.shadowImage = [[UIImage alloc] init];appearance.shadowColor = nil;self.navigationController.navigationBar.scrollEdgeAppearance = appearance;

接著,我們將默認為隱藏的工具欄開啟,并且設置三個不同的按鈕來演示工具欄按鈕的使用。
此處與導航控制器一樣,我們分別采用三種初始化方法,來實現文本,系統風格,和自定義圖像的初始化。

與導航控制器不同的是,此處我們額外使用固定空間按鈕或者彈簧按鈕,實現將工具欄的按鈕以相同間距排列。

    //顯示工具欄對象//默認工具欄是隱藏的self.navigationController.toolbarHidden = NO;self.navigationController.toolbar.translucent = NO;//創建三個工具欄按鈕UIBarButtonItem *btn1 = [[UIBarButtonItem alloc] initWithTitle:@"left" style:UIBarButtonItemStylePlain target:nil action:nil];UIBarButtonItem *btn2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(pressNext)];UIButton *btnImage = [UIButton buttonWithType:UIButtonTypeCustom];[btnImage setImage:[UIImage imageNamed:@"7_.jpg"] forState:UIControlStateNormal];btnImage.frame = CGRectMake(0, 0, 60, 60);UIBarButtonItem *btn3 = [[UIBarButtonItem alloc] initWithCustomView:btnImage];//位置分開//法一:固定控件按鈕
//    UIBarButtonItem *btnF1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
//    
//    btnF1.width = 100;//法二://創建自動計算按鈕,彈簧按鈕UIBarButtonItem *btnF2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];//按鈕數組的創建NSArray *arrayBtns = [NSArray arrayWithObjects:btn1, btnF2, btn2, btnF2, btn3, nil];self.toolbarItems = arrayBtns;}- (void) pressNext
{	//使用此按鈕彈出下一視圖。VCSecend *vc = [[VCSecend alloc] init];[self.navigationController pushViewController:vc animated:YES];}- (void)viewWillAppear:(BOOL)animated {[super viewWillAppear:animated];[self.navigationController setToolbarHidden:NO animated:animated];
}

效果:
在這里插入圖片描述
點擊照相機后:
在這里插入圖片描述
在上面的效果中,當進入第二個視圖我們的工具欄消失了,使用如下代碼實現:
在根視圖中加入:

- (void)viewWillAppear:(BOOL)animated {[super viewWillAppear:animated];[self.navigationController setToolbarHidden:NO animated:animated];
}

在二視圖中加入:

- (void)viewWillAppear:(BOOL)animated {[super viewWillAppear:animated];[self.navigationController setToolbarHidden:YES animated:animated];
}

即可實現。


總結

導航控制器是UI學習的重要一部分,經過這篇總結融會貫通,我覺得我又行咯。

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

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

相關文章

壓縮大文件消耗電腦CPU資源達到33%以上

今天用7-Zip壓縮一個大文件,文件大小是9G多,這時能聽到電腦風扇聲音,查看了一下電腦資源使用情況,確實增加了不少。 下面是兩張圖片,圖片上有電腦資源使用數據。

Spring系統學習 -Spring IOC 的XML管理Bean之bean的獲取、依賴注入值的方式

在Spring框架中,XML配置是最傳統和最常見的方式之一,用于管理Bean的創建、依賴注入和生命周期等。這個在Spring中我們使用算是常用的,我們需要根據Spring的基于XML管理Bean了解相關Spring中常用的獲取bean的方式、依賴注入值的幾種方式等等。…

c++ namespace以及使用建議

命名空間就是用來區分你使用的這個變量和函數是屬于那一塊的。用來防止不同的人所寫函數和變量,名字相同產生沖突。 在寫c代碼的時候,經常會使用標準庫中的函數,使用之前我們必須在前面添加一個std::,因為c標準庫的函數是在命名空…

關閉Cloudflare Pages的訪問策略

curl API 獲取相應的 uid curl -X GET "https://api.cloudflare.com/client/v4/accounts/賬戶標識符/access/apps" \-H "X-Auth-Email: 郵箱" \-H "X-Auth-Key: Global API KEY" \-H "Content-Type: application/json"賬戶標識符是登…

Dubbo面試題甄選及參考答案

目錄 Dubbo是什么? Dubbo的主要使用場景有哪些? Dubbo的核心功能有哪些? Dubbo與Spring框架的集成方式是什么? Dubbo的RPC調用原理是什么? Dubbo的架構中包含哪些核心組件? Provider、Consumer、Registry、Monitor在Dubbo中分別承擔什么角色? Container在Dubbo中…

Maven項目打包成jar項目后運行報錯誤: 找不到或無法加載主類 Main.Main 和 jar中沒有主清單屬性解決方案

已經用maven工程的package功能進行了打包 找不到或無法加載主類 Main.Main 規定主類 主要在maven的配置文件當中 這邊一定要綁定自己的啟動類 jar中沒有主清單屬性 刪掉這一行就行哈 正確的插件代碼 <plugin><groupId>org.springframework.boot</groupId&…

毫米波SDK使用1

本文檔是AM273x等毫米波雷達處理器SDK的配置和使用&#xff0c;主要參考TI的官方文檔《mmwave mcuplus sdk user guide》。這里僅摘取其中重要的部分&#xff0c;其余枝節可參考原文。 2 系統概覽 mmWave SDK分為兩個主要組件:mmWave套件和mmWave演示。 2.1. mmWave套件 mmWa…

AXI Quad SPI IP核基于AXI-Lite接口的標準SPI設計指南

在標準SPI配置下&#xff0c;SPI設備除了包含基本的SPI特性外&#xff0c;還具備以下一些標準功能&#xff0c;這些功能如下所示&#xff1a; 支持FPGA內部的多主設備配置&#xff0c;其中使用單獨的_I&#xff08;輸入&#xff09;、_O&#xff08;輸出&#xff09;、_T&…

FM148A,FM146B運行備件

FM148A,FM146B運行備件。電源保險絲倉主控底座的保險絲倉示意圖底座上共有兩個保險絲&#xff08;800mA&#xff09;&#xff0c;FM148A,FM146B運行備件。&#xff08;10&#xff5e;73&#xff09;30/195主控單元2.K-CUT014槽底座地址接口主控站地址撥開關從上到下為二進制數的…

開發網站,如何給上傳圖片的服務器目錄授權

開發網站&#xff0c;上傳圖像時提示”上傳圖片失敗&#xff0c;Impossible to create the root directory /var/www/html/xxxxx/public/uploads/avatar/20240608.“ 在Ubuntu上&#xff0c;你可以通過調整文件夾權限來解決這個問題。首先&#xff0c;確保Web服務器&#xff08…

【筆記】從零開始做一個精靈龍女-裝備階段

這里只記錄相對重要的步驟和一些思路 但是頭發那塊很詳細哦~ &#xff08;標的小數字不用在意&#xff0c;那個是我網課的時長記錄&#xff09; 耳環 1.創建一個圓環&#xff0c;調整參數 做好后再復制一個小的 肩甲 2.0-2.4 1.創建圓柱體/球體也可 然后把底部的兩個點刪…

在 Unreal Engine 5.4 中加載 5.3 版本的插件

Unreal Engine 的版本更新可能導致插件的兼容性問題。如果你需要在 Unreal Engine 5.4 中加載 5.3 版本的插件&#xff0c;可能需要進行一些手動調整和重新編譯。本文將詳細介紹如何進行這些操作。 步驟 1: 準備插件文件 下載 5.3 版本的插件&#xff1a; 從官方源或插件開發者…

Xsens動作捕捉系統:角色動畫制作與運動分析領域的先進工具

隨著傳感器技術的不斷進步&#xff0c;動作捕捉技術現在更加趨向于民用化&#xff0c;擁有價格優勢的慣性動作捕捉系統現在更多的出現在獨立動畫工作室與國內外多所高校的實際項目應用中。 憑借無場地限制、價格優惠、校準使用方便、數據采集精確等多項優勢&#xff0c;Xsens慣…

[AI Google] 雙子座模型家族迎來新突破:更快的模型、更長的上下文、AI代理等更多功能

Google發布了Gemini模型家族的更新&#xff0c;包括新的1.5 Flash模型&#xff0c;該模型旨在提高速度和效率&#xff0c;以及Project Astra&#xff0c;這是對未來AI助手愿景的展示。1.5 Flash是專為大規模高頻任務優化的輕量級模型&#xff0c;具有突破性的長上下文窗口。同時…

Diffusers代碼學習: IP-Adapter Inpainting

IP-Adapter還可以通過Inpainting自動管道和蒙圖方式生成目標圖片。 # 以下代碼為程序運行進行設置&#xff0c;使用Inpainting 的自動管道&#xff0c; import os os.environ["HF_ENDPOINT"] "https://hf-mirror.com"from diffusers import AutoPipelin…

【java】速度搭建一個springboot項目

使用軟件&#xff1a;IDEA&#xff0c;mysql 使用框架&#xff1a;springboot mybatis-plus druid 坑點 使用IDEA搭建一個springboot項目的時候&#xff0c;需要考慮一下IDEA版本支持的JDK版本以及maven版本。否則再構建項目&#xff0c;引入pom的時候就會報錯。 需要檢查…

04 uboot 編譯與調試

新手不需要詳細掌握 uboot,只需要知道它是一個什么東西即可,工作中也只是改一些參數而已。 1、uboot 是什么 Linux 系統要啟動就必須需要一個 bootloader 程序,也就說芯片上電以后先運行一段 bootloader 程序。這段 bootloader 程序會先初始化 DDR 等外設,然后將 Linux 內…

利用PowerQuery控制數據行數

PowerBI報表在開發的過程中&#xff0c;經常會遇到數據量非常龐大的情況&#xff0c;在這種情況下&#xff0c;本機連接數據源如果不進行特殊處理的話&#xff0c;那么刷新數據的時候可能會發生數據刷新時間過長、數據加載內存錯誤、開發過程中構建DAX卡頓等情況。 那么在實際開…

不確定性+電動汽車!含高比例新能源和多類型電動汽車的配電網能量管理程序代碼!

前言 能源供應的可持續性和清潔性是當今世界共同關注的議題&#xff0c;配電網與可再生能源發電相結合&#xff0c;通過多能互補和梯級利用&#xff0c;在不同時空取長補短&#xff0c;提高能源利用率&#xff0c;減少溫室氣體排放&#xff0c;是解決能源短缺和環境問題的有效…

遞歸及其使用

遞歸及其使用 1. 什么是遞歸&#xff1f;2. 遞歸解決什么問題&#xff1f;3. 遞歸的步驟4. 使用遞歸的注意事項5. 示例 1. 什么是遞歸&#xff1f; 遞歸是指在函數的定義中使用函數自身的過程。簡單來說&#xff0c;遞歸是通過將大問題分解為更小的子問題來解決問題的一種方法…