我有一個viewController顯示使用tableview查詢的結果)。 通過在一行上粘貼我推一個childView,我設置了一個導航條,其中包含右側的兩個按鈕(上一個/下一個)。 我的問題是: 當我點擊上一個或下一個按鈕時,如何切換到上一個或下一個「childView」? 我想在視圖切換時也有一個過渡效果? 有什麼幫助嗎?Iphone導航到上一個/下一個viewController
回答
我有一個觀點,包含一個陣營的列表,並觸摸一個用戶到陣營的細節。我想允許用戶左右滑動以瀏覽顯示每個細節的營地列表。我想要一個顯示滑動的可視化動畫,並且「返回」按鈕始終指向移回導航堆棧,即返回列表。
具有結果表的第一個視圖是唯一知道「上一個」和「下一個」是什麼意思的對象,因此他們將負責實施滑動操作。由於我們將對該視圖中的「當前顯示的」行/部分進行更改,而該視圖不是當前視圖,因此您需要添加變量/屬性來跟蹤該視圖。
因爲導航控制器已經可以對視圖更改進行動畫處理,所以我讓它執行大部分工作。當移動「前一個」時,我創建一個新視圖,其中包含以前的條目詳細信息,將其插入導航堆棧(在LIST視圖和當前DETAIL視圖之間),並執行popViewControllerAnimated,它提供視覺效果並卸載細節視圖只是動畫了。
要移動到「下一個」陣營詳細信息,我創建一個新的視圖,其中包含下一個條目詳細信息,將其添加到導航堆棧的末尾,然後通過刪除細節來清理導航堆棧視圖,只是動畫關閉。
所以,簡而言之: 細節視圖將檢測輕掃手勢並通知父母。 父級確定應顯示的下一個/上一個行。 父代用當前視圖替換當前視圖,左右替換動畫以可視化指示效果。父母也會更新導航堆棧,以確保「返回」按鈕始終充當LIST視圖的彈出窗口,而不是以前顯示的DETAIL視圖。
我不能在這裏發佈我所有的代碼,但下面是大多數。一些具體的陷阱需要提防:
操縱導航堆棧可以在運行時產生錯誤,警告如果試圖刪除VC是動畫的同時。因此,我們等到它完全被替換,然後刪除它,通過註冊爲導航控制器的委託,並使用「didShowViewController」方法來檢測何時可以安全地進行更改。只有在列表中向前移動時才需要此複雜功能,因爲在「後退」邏輯中,導航控制器在popViewController之後自行清理。
爲了使用didShowViewController,您必須設置一個委託。代表不得是可能消失的風險投資,否則你將會崩潰。我只有控制LIST視圖將自己設置爲委託。當你操縱哪個行/部分的用戶正在查看細節時,我還會在隱藏的LIST視圖上移動高亮(並滾動表格),以便當它們最終「返回」到它時,顯示上次查看的項目。
當創建一個詳細視圖,通過在親本中,定義的方法來讓母體知道發生了滑動,並在細節視圖寄存器輕掃識別器,在viewDidLoad方法,
代碼在列表視圖(父)
-(NSString *) nameOfPreviousCampAndUpdateCurrents;
{
// pseudo code
// targetsection = srcSection
// targetrow = srcRow-1.
// if targetrow < 0
// targetsection = srcSection - 1
// targetrow = last row of targetsection
// if targetSection < 0
// return nil;
//
// return name at targetsection, targetrow
NSInteger targetSection;
NSInteger targetRow;
NSString *results = nil;
targetSection = self.currentDetailViewSection;
targetRow = self.currentDetailViewRow-1;
if (targetRow < 0)
{
targetSection--;
if (targetSection <0)
{
return nil;
}// end if
NSInteger numberOfRowsInSection = [self tableView:self.myTable numberOfRowsInSection:targetSection];
targetRow = numberOfRowsInSection-1;
}// end if
results = [self getCampNameInSection:targetSection atOffset:targetRow];
self.currentDetailViewSection = targetSection;
self.currentDetailViewRow = targetRow;
return results;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
CampDetails *detailViewController = [[[CampDetails alloc] initWithNibName:nil bundle:nil] autorelease];
detailViewController.campName = [self getCampNameInSection:indexPath.section atOffset:indexPath.row];
detailViewController.campID = [self getCampIDForSection:indexPath.section atOffset:indexPath.row];
detailViewController.parent = self;
self.currentDetailViewSection = indexPath.section;
self.currentDetailViewRow = indexPath.row;
// ...
// Pass the selected object to the new view controller.
[[self navigationController] pushViewController:detailViewController animated:YES];
//[detailViewController release];
}
-(void) viewDidLoad;
{
// The ROOT view controller should do this.
if ([[self.navigationController viewControllers] count] == 1)
{
self.navigationController.delegate = self;
}// end if
}
-(void) moveToNextCamp;
{
NSString *nextCamp = [self nameOfNextCampAndUpdateCurrents];
if (nextCamp == nil)
{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Warning"
message:@"You are already at the last item in the list of camps."
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}// end if
CampDetails *detailViewController = [[[CampDetails alloc] initWithNibName:nil bundle:nil]autorelease];
detailViewController.campName = nextCamp;
detailViewController.campID = [self getCampIDForSection:self.currentDetailViewSection atOffset:self.currentDetailViewRow];
detailViewController.parent = self;
// do the animation to the right
[self.navigationController pushViewController:detailViewController animated:YES];
// remove the previous controller so that popping the current one takes us "up"
// WHILE THE FOLLOWING CODE DOES WORK, it also results in a runtime warning.
// so instead, we tinker with the controller stack only when it's safe (see below)
// NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
// [viewControllers removeObjectAtIndex:1];
// [self.navigationController setViewControllers:viewControllers animated:NO];
//
// clean up the stack AFTER the child is shown.
self.userJustSwiped = YES;
[self updateTableHighlightAndScrollPosition];
}
-(void) moveToPreviousCamp;
{
NSString *previousCamp = [self nameOfPreviousCampAndUpdateCurrents];
if (previousCamp == nil)
{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Warning"
message:@"You are already at the first item in the list of camps."
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}// end if
CampDetails *detailViewController = [[[CampDetails alloc] initWithNibName:nil bundle:nil]autorelease];
detailViewController.campName = previousCamp;
detailViewController.campID = [self getCampIDForSection:self.currentDetailViewSection atOffset:self.currentDetailViewRow];
detailViewController.parent = self;
// add the controller so that popping the current one takes us there
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
NSInteger lastNavStackEntryIndex = [viewControllers count]-1;
[viewControllers insertObject:detailViewController atIndex:lastNavStackEntryIndex];
[self.navigationController setViewControllers:viewControllers animated:NO];
// do the animation (which also releases the previously current vc)
[self.navigationController popViewControllerAnimated:YES];
[self updateTableHighlightAndScrollPosition];
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// IF we just swiped to a details view, do some clean up
if (self.userJustSwiped)
{
self.userJustSwiped = NO;
// clean up the stack AFTER the child is shown. remove the previous controller so that popping the current one takes us "up"
NSMutableArray *viewControllersArray = [NSMutableArray arrayWithArray:navigationController.viewControllers];
NSInteger lastNavStackEntryIndex = [viewControllersArray count] - 1;
[viewControllersArray removeObjectAtIndex:lastNavStackEntryIndex-1];
[navigationController setViewControllers:viewControllersArray animated:NO];
}// end if
}
-(void) userSwipedLeftOnChild;
{
[self moveToNextCamp];
}
-(void) userSwipedRightOnChild;
{
[self moveToPreviousCamp];
}
代碼在詳細視圖(子):
-(void) leftSwipe:(UIGestureRecognizer*)recognizer;
{
[self.parent userSwipedLeftOnChild];
}
-(void) rightSwipe:(UIGestureRecognizer*)recognizer;
{
[self.parent userSwipedRightOnChild];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// add swipe recognizers
UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(leftSwipe:)];
[leftSwipe setDirection:UISwipeGestureRecognizerDirectionLeft];
[self.view addGestureRecognizer:leftSwipe];
[leftSwipe release];
UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(rightSwipe:) ];
[rightSwipe setDirection:UISwipeGestureRecognizerDirectionRight];
[self.view addGestureRecognizer:rightSwipe];
[rightSwipe release];
}
當輕按這些按鈕時,您可以輕鬆地使用動畫推送和彈出視圖控制器。
如果您需要幫助,請告訴我。
使用一個UINavigationController,它自動有一個後退按鈕,然後在右側添加下一個按鈕。
或者只是隱藏導航控制器的欄,並添加自己的兩個按鈕(我認爲你目前的做法)。
要推/彈出視圖 - 控制一個導航控制器上:
推進到下一個VC:
[myNavController pushViewController:vc animated:YES];
彈出回最後一個VC:
myNavController popViewControllerAnimated:YES];
彈出回第三VC對堆棧:
[myNavController popToViewController:[myNavController.viewControllers objectAtIndex:2] animated:YES];
請注意,如果您想最大限度地減少內存使用量,請使用您自己的導航欄和您自己的按鈕,並確保您只有兩個視圖控制器可以使用您自己編碼的索引/數目來確定您在虛擬堆棧中的位置。
- 1. 從ViewController導航到另一個ViewController
- 2. UIButton導航到另一個ViewController的WebView
- 3. 創建下一個/上一個導航
- 4. 上一個下一個導航
- 5. UIAlertController按鈕點擊導航到一個導航控制器的第一個ViewController
- 6. 兩個導航Controllers-從最後導航到第一的ViewController
- 7. Eclipse導航到下一個/上一個標記的出現
- 8. 如何導航到下一個或上一個過程?
- 9. 導航到另一個視圖iPhone SDK?
- 10. 導航到另一個視圖iPhone SDK?
- 11. 一個ViewController轉到另一個ViewController
- 12. 如何在按下按鈕時以編程方式導航到下一個ViewController?
- 13. iPhone ModalViewController未導航到下一個視圖
- 14. 如何導航到iPhone中的下一個視圖控制器
- 15. 導航到vimdiff的下一個衝突
- 16. 延遲導航到下一個頁面
- 17. PushViewController導航到下一個堆棧
- 18. 上一個/下一個加載導航鏈接的導航問題
- 19. 使不上浮到下一行一個導航欄調整
- 20. 如何在iphone sdk中的單個viewcontroller中從一個視圖導航到另一個視圖?
- 21. iPhone ViewController影響另一個ViewController的IBOutlet
- 22. iOS導航問題:在推送ViewController後,導致顯示前一個ViewController的導航條的導航欄
- 23. 爲什麼導入一個ViewController會導致Xcode無法找到另一個ViewController?
- 24. 從一個webview導航到另一個
- 25. 創建下一個和上一個按鈕以進行導航
- 26. 視差下一個和上一個導航
- 27. 下一個/上一個博客導航的圖像
- 28. 將上一個/下一個導航鏈接與flexbox對齊?
- 29. 響應式上一個和下一個導航
- 30. 固定標題導航和scrollTo()下一個/上一個元素