当展示UIAlertController时,应用程序崩溃

4

当我尝试展示UIAlertController时,我的应用程序崩溃了。

我有一个UIViewController以模态方式呈现,然后在呈现的视图控制器上,当点击某个按钮时,我想展示一个actionSheet警报。

不知何故,在执行此操作时应用程序会崩溃,我无法弄清楚原因。

以下是代码:

let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: "Image from Camera", style: .default, handler: { (_) in
    let cameraController = CameraController()
    self.present(cameraController, animated: true, completion: nil)
}))
alertController.addAction(UIAlertAction(title: "Image from Library", style: .default, handler: {(_) in
    let imagePickerController = UIImagePickerController()
    imagePickerController.delegate = self
    imagePickerController.allowsEditing = true
    self.present(imagePickerController, animated: true, completion: nil)
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
alertController.view.tintColor = UIColor.rgb(red: 46, green: 94, blue: 120)
self.present(alertController, animated: true, completion: nil)

崩溃日志:

libc++abi.dylib: 终止类型为 NSException 的未捕获异常

当我使用 backtrace 函数跟踪错误时,显示如下内容:

    * thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00000001101a7fce libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00000001101e1150 libsystem_pthread.dylib`pthread_kill + 333
    frame #2: 0x000000010fe650e7 libsystem_c.dylib`abort + 127
    frame #3: 0x000000010fbf791f libc++abi.dylib`abort_message + 245
    frame #4: 0x000000010fbf7abb libc++abi.dylib`default_terminate_handler() + 265
    frame #5: 0x0000000109b341be libobjc.A.dylib`_objc_terminate() + 97
    frame #6: 0x000000010fc13159 libc++abi.dylib`std::__terminate(void (*)()) + 8
    frame #7: 0x000000010fc12e0a libc++abi.dylib`__cxa_rethrow + 99
    frame #8: 0x0000000109b340dc libobjc.A.dylib`objc_exception_rethrow + 40
    frame #9: 0x000000010a424a39 CoreFoundation`CFRunLoopRunSpecific + 537
    frame #10: 0x0000000112faf9c6 GraphicsServices`GSEventRunModal + 62
    frame #11: 0x000000010bd325e8 UIKit`UIApplicationMain + 159
    frame #13: 0x000000010fd92d81 libdyld.dylib`start + 1
    frame #14: 0x000000010fd92d81 libdyld.dylib`start + 1

我甚至尝试在主队列上调度演示,但仍然无法工作。有任何提示吗?谢谢。
编辑:为了过滤一些问题,我实现了一个简单的警报控制器,并且仍然会在使用.actionSheet时崩溃,但不会在使用.alert时崩溃。
let alert = UIAlertController(title: "title", message: "message", preferredStyle: UIAlertControllerStyle.actionSheet)
present(refreshAlert, animated: true, completion: nil)

使用这种方式会导致崩溃,但如果使用.alert则不会出现此问题。

为什么会发生这种情况?


我不知道问题是否出在从已经呈现的视图控制器中呈现警报控制器上;但是我以前做过这个而没有任何问题。 - Ivan Cantarino
1
检查该代码是在后台线程中还是从后台线程调用。 - Nitish
@Nitish,正如我所提到的,我已经尝试在主线程中进行调度,但它仍然崩溃。 - Ivan Cantarino
可能与此相关,我注意到了UIColor.rgb()。这是您自己为UIColor编写的自定义扩展方法吗?因为通常提供的颜色值介于0和1之间。祝好运! - Louis Leung
问题不在于UIColor扩展,虽然可能是,但我刚刚尝试了默认颜色,它仍然崩溃。 - Ivan Cantarino
显示剩余2条评论
2个回答

8

我找到了问题所在。

不幸的是,Xcode并没有提供有用的崩溃日志。

问题在于,由于我正在iPad上测试这个UIAlertController,我应该实现警告控制器的源视图。

为了做到这一点,我添加了以下代码,一切都按预期工作:

if UIDevice.current.userInterfaceIdiom == .pad {
    guard let button = self.header?.profileImageButton else { return }
    alertController.popoverPresentationController?.permittedArrowDirections = .right
    alertController.popoverPresentationController?.sourceView = button
}
self.present(alertController, animated: true, completion: nil)

0

弹出警报

这会对我有帮助,我认为这也会对您有帮助。

     let refreshAlert = UIAlertController(title: "Refresh", message: "All data will be lost.", preferredStyle: UIAlertControllerStyle.alert)

    refreshAlert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action: UIAlertAction!) in
        print("Handle Ok logic here")
    }))

    refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction!) in
        print("Handle Cancel Logic here")
    }))

    present(refreshAlert, animated: true, completion: nil)

操作表

    let actionSheetController: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

     create an action
       let firstAction: UIAlertAction = UIAlertAction(title: "First Action", style: .default) { action -> Void in

            print("First Action pressed")
        }

        let secondAction: UIAlertAction = UIAlertAction(title: "Second Action", style: .default) { action -> Void in

            print("Second Action pressed")
        }

        let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in }

    // add actions
    actionSheetController.addAction(firstAction)
    actionSheetController.addAction(secondAction)
    actionSheetController.addAction(cancelAction)

     present an actionSheet...
    present(actionSheetController, animated: true, completion: nil)

}

@seggy:编辑得不太好 :) - Nitish
我猜你是新来的StackOverflow。你分享的答案不是OP正在寻找的答案。OP已经知道你所建议的,但他面临的问题在于代码中。它也可能出现在你编写的相同代码中。 - Nitish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接