使用MonoTouch的UINavigationController和UINavigationBarDelegate.ShouldPopItem()

rih*_*iha 11 back-button uinavigationbar uinavigationcontroller xamarin.ios

当点击UINavigationBar的后退按钮(由UINavigationController控制)时,如何弹出UIAlertView?在某些情况下,我想问用户"你确定吗?" 问题类型,以便他可以中止操作并保持当前视图或弹出导航堆栈并转到父视图.

我发现最吸引人的方法是在UINavigationBar的Delegate上覆盖ShouldPopItem().

现在,这里有一个非常相似的问题:iphone navigationController:在退出当前视图之前等待uialertview响应

还有一些类似性质的其他问题,例如: 检查UIViewController是否即将从导航堆栈中弹出? 以及如何判断在UINavigationControllerStack中按下后退按钮的时间

所有这些状态"子类UINavigationController"作为可能的答案.

然后有一个读取像子类UINavigationController一般不是一个好主意: Monotouch:UINavigationController,覆盖initWithRootViewController

苹果的文档也说的UINavigationController不打算被继承.

其他一些人声称在使用UINavigationController时甚至不能覆盖ShouldPopItem(),因为它不允许将自定义/子类UINavigationBarDelegate分配给UINavigationBar.

我的子类化尝试都没有工作,我的自定义代表没有被接受.

我还在某处读过可能在我的自定义UINavigationController中实现ShouldPopItem(),因为它将自己指定为其UINavigationBar的Delegate.

没什么好吃的,这没用.UINavigationController的子类如何知道属于UINavigationBarDelegate的Methods.它被拒绝:"找不到合适的方法来覆盖".删除已编译的"override"关键字,但完全忽略该方法(如预期的那样).我认为,使用Obj-C可以实现几个协议(类似于C#AFAIK中的接口)来实现这一点.不幸的是,UINavigationBarDelegate不是一个接口而是MonoTouch中的一个类,所以这似乎是不可能的.

我在这里很丢失.当UINavigationBar由UINavigationController控制时,如何在UINavigationBar的Delegate上覆盖ShouldPopItem()?或者有没有其他方法可以弹出UIAlertView并在可能弹出导航堆栈之前等待它的结果?

Gin*_*nny 7

这篇文章有点旧,但如果你仍然对解决方案感兴趣(尽管仍然涉及子类化):

这实现了"你确定要退出吗?" 按下后退按钮时发出警报,从以下代码进行修改:http://www.hanspinckaers.com/custom-action-on-back-button-uinavigationcontroller/

事实证明,如果在CustomNavigationController中实现UINavigationBarDelegate,则可以使用shouldPopItem方法:


CustomNavigationController.h:

#import <Foundation/Foundation.h>

@interface CustomNavigationController : UINavigationController <UIAlertViewDelegate, UINavigationBarDelegate> {

BOOL alertViewClicked;
BOOL regularPop;
}

@end
Run Code Online (Sandbox Code Playgroud)

CustomNavigationController.m:

#import "CustomNavigationController.h"
#import "SettingsTableController.h"

@implementation CustomNavigationController


- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {

if (regularPop) {
    regularPop = FALSE;
    return YES;
}

if (alertViewClicked) {
    alertViewClicked = FALSE;
    return YES;
}

if ([self.topViewController isMemberOfClass:[SettingsTableViewController class]]) {
    UIAlertView * exitAlert = [[[UIAlertView alloc] initWithTitle:@"Are you sure you want to quit?" message:nil delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Yes", nil] autorelease];

    [exitAlert show];

    return NO;

}   
else {
    regularPop = TRUE;
    [self popViewControllerAnimated:YES];
    return NO;
}   
}

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
    //Cancel button
}

else if (buttonIndex == 1) {    
        //Yes button
    alertViewClicked = TRUE;
    [self popViewControllerAnimated:YES];
}           
}

@end
Run Code Online (Sandbox Code Playgroud)

使用"regularPop"bool的奇怪逻辑是因为出于某种原因只在"shouldPopItem"上返回"YES"而只弹出导航栏,而不是与navBar关联的视图 - 为此,您必须直接调用popViewControllerAnimated(然后调用shouldPopItem as它的一部分逻辑.)

  • 谢谢,这完美无缺.花了我几个小时试图弄清楚为什么只有条形图会弹出而不是视图,并且确实添加了"regularPop",因为你建议解决问题. (2认同)

rih*_*iha 3

作为参考,我放弃后采取的路线ShouldPopItem()是将后退按钮替换为UIBarButtonItem具有自定义UIButton分配的CustomView。它的UIButton设计看起来像原始的后退按钮,使用两个图像来表示正常状态和按下状态。最后需要隐藏原来的后退按钮。

对于它应该做的事情来说,代码太多了。是的,谢谢苹果。

顺便说一句:另一种可能性是创建一个UIButton带有秘密UIButtonType101(实际上是后退按钮)的 ,但我避免了这种情况,因为它可能会在任何更高版本的 iOS 版本中崩溃。


归档时间:

查看次数:

8653 次

最近记录:

10 年,3 月 前