导航控制器 UI_08(上)

本文详细介绍了UINavigationController的使用方法,包括其基本概念、页面间的跳转原理及如何进行页面传值等核心内容。此外还提供了丰富的代码示例,帮助读者更好地理解和掌握导航控制器的运用。
主要内容:UINavigationController 重要:属性传值(向后一个界面传值)、代理传值(向前相邻的界面传值)、单例传值(不相邻的界面向前传值)
1、UINavigationController   导航控制器,是用来管理多个单视图控制器的控制器,此时他管理的多个单视图控制器之前有一定的层级关系(依赖关系,即下一个页面的出现要依赖于上一个页面),导航视图控制器创建时也会自带一个View,之不过此时它上面有来年各个子视图,一个是contentView ,一个是navigationBar  管理的多个单视图控制器自带的view都添加到contenView上面导航控制器在完成页面之间的跳转的时候是一个不断地创建和销毁的过程
导航控制器 <wbr>UI_08(上)

 UINavigationController  在管理视图的时候用的栈的数据结构,进入下一界面入栈,此时要创建下一级页面视图;返回上一级界面就是出栈,此时会把当前视图界面销毁
======================================================
AppDelegate.m
    //创建单是图控制器FirstVC
   
FirstViewController *firstVC = [[FirstViewController alloc]init];
   
//创建导航控制器对象
   
UINavigationController *navigationVC = [[UINavigationController alloc]initWithRootViewController:firstVC];
   self.window.rootViewController = navigationVC;
    [firstVC retain];
    [navigationVC release];
——————————————————————————————
FirstViewController.m
 1.引入下一级的头文件
#import "SecondViewController.h"
补充内容:
- (void)viewWillAppear:(BOOL)animated{
   
NSLog(@"%s",__FUNCTION__);
}
- (void)viewDidAppear:(BOOL)animated{
   
NSLog(@"%s",__FUNCTION__);
}
- (void)viewWillDisappear:(BOOL)animated{
    NSLog(@"%s",__FUNCTION__);
}
- (void)viewDidDisappear:(BOOL)animated{
   
NSLog(@"%s",__FUNCTION__);
}
- (void)viewDidLoad {
    [super viewDidLoad];
    //制定背景颜色,消除跳转的重影现象
   self.view.backgroundColor = [UIColor whiteColor];
    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
    button1.
frame = CGRectMake(80, 100, 150, 40) ;
    [button1
setTitle:@"欢迎进入下一个页面" forState:UIControlStateNormal];
   
//添加关联事件
    [button1
addTarget:self action:@selector(handlePush : ) forControlEvents:(UIControlEventTouchUpInside)];
    button1.
backgroundColor = [UIColor greenColor];
    [self.view addSubview:button1];    
}
//配置导航条公共的属性,该属性作用于所有的界面
- (
void)configureCommonProerty{
   
//设置导航条的颜色
   
self.navigationController.navigationBar.barTintColor = [UIColor cyanColor];
   
   
//控制导航条的毛玻璃效果是否打开,影响的是contentView上视图的布局
   
self.navigationController.navigationBar.translucent = YES;
   
//设置导航条是否隐藏
   
self.navigationController.navigationBarHidden = NO;
   
//设置导航条内容颜色(标题,视图边框的颜色)
   
//设置导航条Back的颜色
   
self.navigationController.navigationBar.tintColor = [UIColor redColor];
   
//设置导航条的背景图片
   
//44的高时图片只能早导航条上
   
//64的高时,导航条和状态栏都有
   
//其他情况拉伸或者压缩

    [
self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"95"] forBarMetrics:UIBarMetricsDefault];
}
//针对于每个界面单独定制导航条上的内容
- (
void)customNavigationItemAppearance{
   
//1.配置导航条显示的标题
   
self.navigationItem.title = @"FirstVC";
   
//2.配置导航条的标题视图
   
UISegmentedControl *segmentView = [[UISegmentedControl alloc]initWithItems:@[@"所有通话",@"未接来电"]];
   
self.navigationItem.titleView = segmentView;
   
    [segmentView
release];
   
//3.0配置导航条的左右按钮
    //self 为试图控制器对象

    UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]initWithTitle:@"添加" style:UIBarButtonItemStylePlain target:self action:@selector(handleLeftItem :)];
   
self.navigationItem.leftBarButtonItem = leftItem;
    [leftItem
release];
   
   UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(handleRight :)];

    self.navigationItem.rightBarButtonItem = rightItem;
    [rightItem release];
}
#pragma mark  实现左barButton的方法
- (void)handleLeftItem : (UIBarButtonItem *)leftItem{
   
NSLog(@"添加");
}
#pragma mark 实现右BarbuttonItem 的方法
- (void)handleRight : (UIBarButtonItem *)rightItem{
   
NSLog(@"垃圾桶");
}
- (void)handlePush :  (UIButton *)push{
//    NSLog(@"欢迎进入第一个页面");
   
//2.创建SecondViewController对象
   
SecondViewController *secondVC = [[SecondViewController alloc]init];
   
//3.获取导航视图控制器并完成跳转
//    self.navigationController  获取当前视图的导航控制器对象
   
//第一个参数:待跳转的试图控制器对象
  
// 第二个参数:是否需要动画
    [self.navigationController pushViewController:secondVC animated:YES];
    //释放
    [secondVC
release];
}
- (void)handlePush :  (UIButton *)push{
//    NSLog(@"欢迎进入第一个页面");
   
//2.创建SecondViewController对象
   
SecondViewController *secondVC = [[SecondViewController alloc]init];
   
//3.获取导航视图控制器并完成跳转
//    self.navigationController  获取当前视图的导航控制器对象
   //第一个参数:待跳转的试图控制器对象
   // 第二个参数:是否需要动画
    [self.navigationController pushViewController:secondVC animated:YES];
    //释放
    [secondVC release];
}
——————————————————————————————
SecondViewController.m
当界面切换的时候,来年各个视图A和视图B的消失的过程
 从A Push  B(从前到后)
 A(viewWillDisAppear:) -> B(viewWillAppear:) -> A(viewDidAppear:) -> B(viewDidAppear:)
 从B pop 到 A(从后到前)
  B(viewWillDisAppear:) -> A(viewWillAppear:) -> B(viewDidAppear:) -> A(viewDidAppear:)
视图将要出现的时候触发,此方法主要用来刷新UI界面
- (void)viewWillAppear:(BOOL)animated{
   
NSLog(@"%s",__FUNCTION__);
}
//视图已经出现的时候触发
- (
void)viewDidAppear:(BOOL)animated{
   
NSLog(@"%s",__FUNCTION__);
}
//视图将要消失的时候触发
- (
void)viewWillDisappear:(BOOL)animated{
   
NSLog(@"%s",__FUNCTION__);
}
//视图已经消失的时候触发
- (
void)viewDidDisappear:(BOOL)animated{
   
NSLog(@"%s",__FUNCTION__);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    //制定背景颜色,消除跳转的重影现象
   self.view.backgroundColor = [UIColor whiteColor];
    UIButton *button1 = [UIButton buttonWithType:(UIButtonTypeSystem)];
    button1.
frame = CGRectMake(80, 100, 150, 40);
    [button1
setTitle:@"欢迎进入下一个页面" forState:UIControlStateNormal];
    button1.
backgroundColor = [UIColor yellowColor];
        [button1
addTarget:self action:@selector(handlePush : ) forControlEvents:(UIControlEventTouchUpInside)];
    [self.view addSubview:button1];
}
- (
void)handlePush : (UIButton *)push{
   
ThirdViewController *thirdVC = [[ThirdViewController alloc]init];
    [
self.navigationController pushViewController:thirdVC animated:YES];
    [thirdVC release];  
}
self.navigationItem.title = @"SecondVC";
第三个控制图省略和上面第三个一样。
——————————————————————————
ForthViewController.m//第四部分实行跳转pop或push
布局部分和第一、二、三个一致(在此省略)
- (void)handelePush : (UIButton *)push{
    1.返回上一级界面 也是有导航视图控制器完成
    [self.navigationController popViewControllerAnimated:YES];
导航控制器 <wbr>UI_08(上)


————————————————————————————————

    2.返回到导航控制器的根视图控制器对象
    [self.navigationController popToRootViewControllerAnimated:YES];
导航控制器 <wbr>UI_08(上)


——————————————————————————————————————
    3.返回到指定的视图控制器
    第一步获取导航视图控制器所有单视图控制器
    NSArray *controllerArray = [self.navigationController viewControllers];
    第二步返回到指定的视图控制器
    [self.navigationController popToViewController:controllerArray[1] animated:YES];    
}
导航控制器 <wbr>UI_08(上)

说明:

导航控制器是通过栈的形式来管理子控制器的(先进后出)

显示在导航控制器上得view永远是栈顶控制器的view

一个导航控制器只有一个导航条,也就是说所有的自控制器公用一个导航条。
======================================================
下接:
UIPassValue页面传值——UI-第八天(下):

欢迎学习本文,未经博主许可,禁止转载!
<think>好的,我现在需要处理用户关于PCL库中getMinMax3D函数重载的问题。用户提到所有重载都不接受3个实参,并给出了四个不同的函数签名。首先,我需要理解用户的问题是什么。用户可能在调用这些函数时传入了3个参数,但编译器报错说没有匹配的重载,所以用户想知道哪里出错了,或者如何正确使用这些函数。 首先,我要回忆一下PCL库中的getMinMax3D函数的作用。这个函数通常用于计算点云在3D空间中的最小和最大坐标值,即点云的包围盒。不同的重载版本可能适用于不同类型的点云数据(比如PCLPointCloud2和模板化的PointT类型),或者有不同的参数需求。 接下来,我需要仔细查看用户提供的四个函数签名,分析它们的参数列表: 1. 第一个版本: void getMinMax3D(const pcl::PCLPointCloud2ConstPtr &amp;cloud, int x_idx, int y_idx, int z_idx, Eigen::Vector4f &amp;min_pt, Eigen::Vector4f &amp;max_pt) 参数数量:6个(cloud, x_idx, y_idx, z_idx, min_pt, max_pt) 2. 第二个版本: void getMinMax3D(const pcl::PCLPointCloud2ConstPtr &amp;cloud, int x_idx, int y_idx, int z_idx, const std::string &amp;distance_field_name, float min_distance, float max_distance, Eigen::Vector4f &amp;min_pt, Eigen::Vector4f &amp;max_pt, bool limit_negative = false) 参数数量:10个,其中limit_negative有默认值,所以可能可以传9个参数。 3. 第三个版本(模板函数): template <PointT> void getMinMax3D(const typename pcl::PointCloud<PointT>::ConstPtr &amp;cloud, const std::string &amp;distance_field_name, float min_distance, float max_distance, Eigen::Vector4f &amp;min_pt, Eigen::Vector4f &amp;max_pt, bool limit_negative = false) 参数数量:7个,其中limit_negative有默认值,可能可以传6个。 4. 第四个版本(模板函数): template <PointT> void getMinMax3D(const typename pcl::PointCloud<PointT>::ConstPtr &amp;cloud, const std::vector<int> &amp;indices, const std::string &amp;distance_field_name, float min_distance, float max_distance, Eigen::Vector4f &amp;min_pt, Eigen::Vector4f &amp;max_pt, bool limit_negative = false) 参数数量:8个,limit_negative有默认值,可能传7个。 用户提到“所有重载均不接受3个实参”,说明他在调用时可能只传入了3个参数,比如cloud、min_pt、max_pt,但所有现有的重载都需要更多参数。比如第一个版本需要至少6个参数,而其他版本也需要更多的参数。 接下来,我需要思考用户可能的错误场景。例如,用户可能想简单地调用getMinMax3D(cloud, min_pt, max_pt),但发现没有这样的重载。这时,正确的做法是检查参数是否匹配现有重载,或者是否使用了正确的点云类型。 另外,可能用户在使用模板版本时没有正确实例化模板,或者传递的参数类型不匹配。例如,对于模板版本,可能需要显式指定PointT类型,或者确保点云类型是pcl::PointCloud<PointT>而不是PCLPointCloud2。 还需要注意不同版本之间的区别:前两个版本接受PCLPointCloud2类型的点云,后两个是模板化的,接受PointCloud<PointT>类型。参数中的x_idx, y_idx, z_idx可能用于指定坐标字段在点云中的索引,而distance_field_name可能用于距离过滤。 用户可能需要根据使用的点云类型选择合适的重载。例如,如果使用PCLPointCloud2,需要提供x、y、z的索引;如果使用PointXYZ类型的点云,可能需要使用模板版本,并且不需要索引,因为坐标字段是已知的。 总结用户的问题,他们可能在调用时参数数量不足,或者参数类型不匹配,导致找不到合适的重载。解决方案是检查点云类型,并传递所需的参数,如索引或距离过滤参数,或者使用正确的函数版本。 最后,我需要将这些分析整理成用户容易理解的步骤,说明每个函数的使用场景和参数要求,并给出示例调用方式,帮助用户正确调用合适的重载函数。</think>在 PCL (Point Cloud Library) 中,`getMinMax3D` 函数用于计算点云的三维包围盒(最小/最大坐标值)。你列出的四个重载版本存在 **参数数量和类型差异**,以下是详细解析: --- ### **核心区别对比表** | 重载版本 | 点云类型 | 关键参数 | 适用场景 | |---------|----------|---------|---------| | **第1个** | `PCLPointCloud2` | `x/y/z_idx` (坐标字段索引) | 需要手动指定坐标字段位置 | | **第2个** | `PCLPointCloud2` | `distance_field_name` (距离过滤) | 带距离阈值过滤的点云处理 | | **第3个** | 模板化 `PointT` | `distance_field_name` | 模板化点云 + 距离过滤 | | **第4个** | 模板化 `PointT` | `indices` (点云索引) | 指定点云子集 + 距离过滤 | --- ### **详细参数说明** #### 1. 基础版本(无过滤) ```cpp void getMinMax3D( const pcl::PCLPointCloud2ConstPtr &amp;cloud, // 输入点云 int x_idx, int y_idx, int z_idx, // XYZ坐标字段的索引 Eigen::Vector4f &amp;min_pt, // 输出最小坐标 Eigen::Vector4f &amp;max_pt // 输出最大坐标 ); ``` - **使用场景**:当点云数据为 `PCLPointCloud2` 格式且需要手动指定坐标字段位置时。 - **示例**: ```cpp pcl::PCLPointCloud2::Ptr cloud(new pcl::PCLPointCloud2); Eigen::Vector4f min_pt, max_pt; // 假设 x 字段索引为 0, y 为 1, z 为 2 pcl::getMinMax3D(cloud, 0, 1, 2, min_pt, max_pt); ``` #### 2. 带距离过滤的版本 ```cpp void getMinMax3D( const pcl::PCLPointCloud2ConstPtr &amp;cloud, int x_idx, int y_idx, int z_idx, const std::string &amp;distance_field_name, // 距离字段名称(如 "range") float min_distance, float max_distance, // 距离阈值范围 Eigen::Vector4f &amp;min_pt, Eigen::Vector4f &amp;max_pt, bool limit_negative = false // 是否反向过滤 ); ``` - **使用场景**:需根据距离字段(如激光雷达的 `range`)过滤点云后再计算包围盒。 --- #### 3. 模板化版本(自动坐标字段) ```cpp template <typename PointT> void getMinMax3D( const typename pcl::PointCloud<PointT>::ConstPtr &amp;cloud, // 模板化点云 const std::string &amp;distance_field_name, // 距离字段名 float min_distance, float max_distance, // 距离阈值 Eigen::Vector4f &amp;min_pt, Eigen::Vector4f &amp;max_pt, bool limit_negative = false ); ``` - **使用场景**:处理模板化点云(如 `pcl::PointXYZ`),自动获取坐标字段,无需手动指定索引。 - **示例**: ```cpp pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); Eigen::Vector4f min_pt, max_pt; pcl::getMinMax3D<pcl::PointXYZ>(cloud, "range", 0.5f, 10.0f, min_pt, max_pt); ``` --- #### 4. 带索引的模板化版本 ```cpp template <typename PointT> void getMinMax3D( const typename pcl::PointCloud<PointT>::ConstPtr &amp;cloud, const std::vector<int> &amp;indices, // 点云索引(指定子集) const std::string &amp;distance_field_name, float min_distance, float max_distance, Eigen::Vector4f &amp;min_pt, Eigen::Vector4f &amp;max_pt, bool limit_negative = false ); ``` - **使用场景**:仅计算点云中指定索引范围内的点的包围盒。 --- ### **错误排查** 若遇到 _"所有重载均不接受 3 个实参"_ 错误,通常是因为: 1. **参数数量不足**:所有重载至少需要 6-8 个参数。 2. **点云类型不匹配**: - 使用 `PCLPointCloud2` 时需提供 `x/y/z_idx`。 - 使用模板化版本时需明确指定 `PointT`(如 `pcl::PointXYZ`)。 3. **未包含头文件**:确保已包含 `#include <pcl/common/io.h>`。 --- ### **总结** 根据你的点云数据类型选择对应重载: - **`PCLPointCloud2`** → 使用第1或第2个版本(需手动指定坐标索引)。 - **模板化点云**(如 `PointXYZ`)→ 使用第3或第4个版本(自动处理坐标)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值