我正在使用Xamarin,在更新到iOS 7 sdk后,我的应用程序一直崩溃...我有一个函数,我从第一个视图控制器传递到我的第二个视图控制器,作为一个简单的动作:
public void Dismiss()
{
try{
this.PresentedViewController.DismissViewController (false, null);
}
catch(Exception ex)
{
string filePath = Path.Combine(path, "log.txt");
File.AppendAllText(filePath,"\n" + DateTime.Now + "\tISSUE:\t Closing colletions detail tab...\n\n" + ex.Message + " " + ex.StackTrace);
}
}
现在应用程序即使在捕获异常后也会崩溃。在我的日志中打印的内容是:
Objective-C exception thrown. Name: NSInvalidArgumentException Reason: [UILabel backdropView:willChangeToGraphicsQuality:]: unrecognized selector sent to instance 0x18c8ee40 at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging:void_objc_msgSendSuper_bool_IntPtr (intptr,intptr, bool, intptr) at MonoTouch.UIKit.UIViewController.DismissViewController(Boolean animated, MonoTouch.Foundation.NSAction completionHandler) [0x00057] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIViewController.g.cs 747 at YltraRoute.MainViewController.CloseCollectionDetailTab()[0x00011]...
我甚至不知道从哪里开始。那里帮助不大。
哦,它并不总是[UILabel backdropView ...它的某个时候UIScrollViewPanGuestureRecognizer
所以我做了更多搜索,似乎这可能是一个内存问题(对象已经被垃圾收集)。
我从here获得了该信息,因为另一个版本的错误是:
Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[__NSCFType backdropView:willChangeToGraphicsQuality:]: unrecognized selector sent to instance 0x1eb3ad70
所以如果确实如此,我该怎么做呢。呈现视图控制器无法正确发布吗?并且呈现的视图控制器也在我的类中全局声明。
答案 0 :(得分:0)
您不必使用.DismissViewController
方法。我会试着解释原因。
导航到新的ViewController时,使用PushViewController
方法。您在参数内创建的视图将添加到堆栈中。所以,例如:
因此,当您打开应用程序时,堆栈如下所示:
| |
| |
| |
| A |
使用PushViewController
添加B和C时,它看起来像这样:
| |
| C |
| B |
| A |
现在,我听到你问:但为什么我不必使用DismissViewController
方法?好吧,还有另一个名为PopToViewController
的方法。这用于导航到已经在堆栈上的另一个ViewController。在该示例中,您当前位于ViewController C内部(因为它位于堆栈顶部)。如果您想导航到ViewController B,您可以搜索堆栈以确定它在那里,然后导航到它。这里有一小段代码:
ViewController_B view_B = null;
foreach (var item in this.NavigationController.ViewControllers)
{
if (item is ViewController_B)
{
view_B = (ViewController_B)item;
}
}
if (view_B != null)
{
this.NavigationController.PopToViewController (view_B, true);
}
现在,发生了什么,你将弹出到ViewController B,但由于它不是堆栈的顶部,它抛弃(垃圾收集)ViewController C.这样,你不需要手动解除C.
如果你想从ViewController C导航到ViewController A,同样如此。但是现在,它抛弃了ViewController C和ViewController B.
但是如果我想导航到的ViewController还不存在呢?您可以在我刚粘贴的示例代码下添加else
语句,如下所示:
if (view_B != null)
{
this.NavigationController.PopToViewController (view_B, true);
}
else
{
this.NavigationController.PushViewController (new ViewController_D, true);
}
请注意,此方法仅在使用ViewControllers时才有效,您可以在其中放置UI(public class ViewController_B : UIViewController
)。
要添加如何从一个ViewController to another
调用方法的问题的答案(当导航到它时),有几个选项。我将列出我使用的方法。
导航到另一个ViewController
时,使用PopToViewController
或PushViewController
,Virtual
方法(来自抽象类UIViewController
){{1将永远被调用。如果您希望每次导航到ViewWillAppear
时执行一次操作,则可以将其置于此重写方法中。
我希望这些信息对您有所帮助。祝你好运!
爱和问候, 的Björn