使用带有 2 个可切换视图和一个分段控件的导航
Posted
技术标签:
【中文标题】使用带有 2 个可切换视图和一个分段控件的导航【英文标题】:Using UINavigation with 2 toggleable views and a UISegmented control 【发布时间】:2014-04-22 01:39:49 【问题描述】:我有一个UISegmentedControl
和两个UICollectionViews
。
这个UISegmentedControl
可以在我的两个集合视图之间切换。
看看这张图片。在 UISegmentedControl 的左侧,您会看到分段控件上的单个项目视图显示视图按钮,该按钮的右侧是网格显示按钮。
网格显示按钮链接到 _collectionView 单个文件显示按钮链接到_collectionView2
默认情况下,我的应用会显示首次访问的 _collectionView。假设我点击了优化按钮。我的 UINavigation 将我带到另一个页面,然后如果我点击该页面上的后退按钮,它将带我回到 _collectionView 页面。
现在假设我点击单个文件显示按钮将我带到下图所示的 _collectionView2 页面。如果我然后点击优化按钮,然后点击返回以带我回到 _collectionView2 页面,它会显示 _collectionView 页面。
_collectionView 是在界面生成器中创建的,我猜它会在每次 viewWillAppear 运行时重新创建并替换 _collectionView2。我试图将它隐藏在 viewWillAppear 例如[_collectionView setHidden:YES];
隐藏它并显示 _collectionView2。
单个文件显示:
这是 UISegmentedControl 的代码:
- (void)displayTypeSegmentSelected
_selectedDisplayTypeIndex = [_displayTypeControl selectedSegmentIndex];
if (_selectedDisplayTypeIndex == 0)
NSLog(@"Single file item view selected");
_fromCollectionView = _collectionView;
_toCollectionView = _collectionView2;
else
NSLog(@"Grid style view selected");
_fromCollectionView = _collectionView2;
_toCollectionView = _collectionView;
[_fromCollectionView removeFromSuperview];
[_toCollectionView setFrame:[_superView bounds]];
[_superView addSubview:_toCollectionView];
[self createFilterBar];
问题:
有没有办法让 UINavigation 实例知道它是从单个文件显示视图导航到的,这样当我单击返回时它不会重新加载 _collectionView?但将 make 带回 _collectionView?
更新 - 根据要求查看代码:
- (void)viewWillAppear:(BOOL)animated
[super viewWillAppear:animated];
NSLog(@"view will appear");
// Create flow layout
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
// Set up margins, sizes etc
[layout setHeaderReferenceSize:CGSizeMake(50,93)];
[layout setItemSize:CGSizeMake(300, 500)];
[layout setMinimumLineSpacing:0];
[layout setMinimumInteritemSpacing:0];
[layout setSectionInset:UIEdgeInsetsMake(1, 0, 40, 0)];
[layout setScrollDirection:UICollectionViewScrollDirectionVertical];
// Initialise collection view 2 with frame, attach layout
_collectionView2 = [[UICollectionView alloc] initWithFrame:[[_thisController view] frame] collectionViewLayout:layout];
// Set background colour, delegate and dataSource
[_collectionView2 setBackgroundColor:[UIColor whiteColor]];
[_collectionView2 setDelegate:_thisController];
[_collectionView2 setDataSource:_thisController];
// Grab nib header nib file and give it a reuse identifier
[_collectionView2 registerNib:[UINib nibWithNibName:@"VAGHeaderLabelReusableView" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView2"];
// Grab cell nib file and give a reuse identifier
[_collectionView2 registerNib:[UINib nibWithNibName:@"VAGGarmentCell2" bundle:nil] forCellWithReuseIdentifier:@"Cell2"];
// Add as subview of this controller
[_collectionView2 setFrame:[[_thisController view] bounds]];
// [[_thisController view] addSubview:_collectionView2];
[_thisController setTitle:@"S H O P"];
// Set to yes so back button isn't hidden and disabled. Note that back title is set to blank on controller that pushes to this one
[[_thisController navigationItem] setLeftItemsSupplementBackButton: YES];
// Create nav bar buttons
UIBarButtonItem *searchButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"magnify_glass.png"] style:UIBarButtonItemStylePlain target:_thisController action:@selector(searchButtonTapped)];
[[_thisController navigationItem] setLeftBarButtonItem:searchButton];
UIBarButtonItem *shoppingCartButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"shopping_cart.png"] style:UIBarButtonItemStylePlain target:_thisController action:@selector(shoppingCartButtonTapped)];
UIBarButtonItem *addFavouriteButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"add_fav_heart.png"] style:UIBarButtonItemStylePlain target:_thisController action:@selector(addFavouriteButtonTapped)];
[[_thisController navigationItem] setRightBarButtonItems:@[shoppingCartButton, addFavouriteButton] animated: YES];
// Reset refine button colour back to clear after returning from refineButtonTableViewController
[_refineButton setBackgroundColor:[UIColor clearColor]];
[_navigationBar setBarTintColor:[UIColor whiteColor]];
[_navigationBar setTranslucent:NO];
// Create filter bar
[self createFilterBar];
【问题讨论】:
你不应该这样做——当你回到视图控制器时,它的子视图应该和你离开时一样。 _collectionView 不应该在每次 viewDidAppear 执行时都重新创建,除非你告诉它这样做。您要使用“返回”按钮返回吗?您应该在 viewDidAppear 中显示带有 2 个集合视图的控制器的代码。 是的,使用“返回”按钮返回。我添加了 viewWillAppear 的代码。问题是我在 viewWillAppear 中没有做任何与 _collectionView 相关的事情。该集合视图是在界面生成器中创建的。我有一个已连接到界面生成器中的 _collectionView 的商店按钮。默认情况下 _collectionView 是点击该按钮时显示的内容。我不知道发生了什么与我添加和删除集合视图的方式有关。这就像导航不知道 _collectionView2 在屏幕上,只是在我点击返回后加载 _collectionView。 导航控制器在加载视图方面没有做任何事情,它正在加载视图控制器。到目前为止,我在您发布的代码中没有看到任何会导致您出现问题的内容。如果你能把你的项目上传到某个地方,或者直接发给我,我很乐意看看。 【参考方案1】:我在一个项目中遇到过类似的情况,我们决定简单地更改一个集合视图的单元格并重新加载集合视图,而不是使用两个单独的集合视图。我认为这将解决您的问题,并且由于您继续只管理一个集合视图,因此您可以减少实施的麻烦。您只需在 cellForItemAtIndexPath
方法中查看当前的可视化选择。从概念上讲,您将其实现为:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
if (self.currentSelection == kSingleView)
return [self cellForSingleView];
else
return [self cellForGridView];
如果您有多种可视化样式,您显然需要检查更多值。然后在您的 viewWillAppear 中,您只需重新加载集合视图。或者,您可能只想在 viewDidLoad 中加载集合视图,因为当视图控制器“弹出”到时不会调用它。这也是使用枚举来定义样式的好时机,因为枚举比常量更具可扩展性。
编辑
为此,您还必须检查您当前的选择并在sizeForItemAtIndexPath
中设置所需的单元格大小:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
if (self.currentSelection == kSingleView)
// return size of Single View Cell
else
// return size of Grid View Cell
另外,请确保您为每个单元格使用不同的单元格标识符。
【讨论】:
所以基本上检测一个段何时被点击,然后为该段返回适当的单元格,例如网格还是单个文件? 检测何时点击段,通过段的索引将选择设置为保持当前选择的 ivar(例如kSingleView
),重新加载您的集合视图,然后在您的 cellForItemAtIndexPath
方法中检查对于当前的可视化选择并返回相应的单元格。
我最终通过模态显示视图解决了这个问题。【参考方案2】:
我通过模态显示视图并使用取消按钮将其关闭来解决此问题。对新控制器进行子类化,并在该文件中创建了一个连接到我的取消按钮的操作,其中包含在点击取消按钮时关闭控制器的代码。
#import "VAGRefineResultsTableViewController.h"
@interface VAGRefineResultsTableViewController ()
@end
@implementation VAGRefineResultsTableViewController
- (id)initWithStyle:(UITableViewStyle)style
self = [super initWithStyle:style];
if (self)
// Custom initialization
return self;
- (void)viewDidLoad
[super viewDidLoad];
// Do stuff here
- (IBAction)cancelButtonTapped:(id)sender
[self dismissViewControllerAnimated:YES completion:NULL];
【讨论】:
以上是关于使用带有 2 个可切换视图和一个分段控件的导航的主要内容,如果未能解决你的问题,请参考以下文章
在带有分段控件的 UITabBarController 中模态显示导航视图控制器