设计一个提供自己的模态 UI 的 iOS 静态库的最简单方法是什么?
我正在设计一个 iOS 静态库,供其他开发人员使用。该库需要提供自己的模式 UI。我正在寻找最简单的方法来设计应用程序和该库之间的接口来完成此任务。我只需要支持iOS 4.0及以上版本。
粗略架构
我的静态库有一个非常简单的 API,只有一个类。应用程序的 AppDelegate 实例化这一类并将其自身设置为委托,以便它可以接收通知。当应用程序希望库显示其 UI 时,它会调用一个方法,然后当库完成其工作时,它会通过委托协议的方法之一发送通知。
我可以看到两种方法来实现这一目标。
选项 1
当应用程序希望库显示其 UI 时,AppDelegate 传入 self.window,库设置其自己的根视图控制器,从而有效地获得 UI 的完全所有权。当 UI 完成时,它会通知 AppDelegate,然后 AppDelegate 在窗口上设置自己的根视图控制器,收回 UI 的所有权。
选项 2
该库公开了一个视图控制器,应用程序可以将其推送到它喜欢的任何视图堆栈上。当库通知 UI 已完成时,应用程序还负责删除视图控制器。
问题
对于选项 1,在运行应用程序期间更改根视图控制器可能会出现问题。使用选项 2,提供可以在任意上下文中工作的视图控制器(作为全窗口视图控制器、作为 UINavigationController 的子视图等)可能会出现问题。
这两个选项的另一个问题是 AppDelegate 可能收到的其他 UIApplicationDelegate 通知,例如 applicationWillResignActive: 和 applicationDidBecomeActive:。库可能需要处理类似的通知才能正确维护其 UI。当其 UI 处于活动状态时,AppDelegate 是否必须将其中每一个传递给库?
还有我没有想到的更好的选择3吗?
I'm designing an iOS static library that will be used by other developers. This library needs to provide its own modal UI. I'm looking for the simplest way to design the interface between the application and this library to accomplish this. I only need to support iOS 4.0 and above.
Rough architecture
My static library has a very simple API with one class. The application's AppDelegate instantiates this one class and sets itself as a delegate so it can receive notifications. When the application wants the library to show its UI it calls a single method, and then when the library is done with its work it sends a notification through one of the delegate protocol's methods.
I can see two ways to accomplish this.
Option 1
When the application wants the library to show its UI, The AppDelegate passes in self.window, and the library sets its own root view controller, effectively taking full ownership of the UI. When the UI is finished, it notifies the AppDelegate, which then sets its own root view controller on the window, taking back ownership of the UI.
Option 2
The library exposes a view controller, which the app can push onto whatever view stack it likes. The app is also responsible for removing the view controller when the library notifies it that the UI is finished.
Issues
With option 1, there may be problems changing root view controllers while in the middle of running an application. With option 2, there may be problems providing a view controller that can work in an arbitrary context (as a full-window view controller, as a sub-view of a UINavigationController, etc).
Another problem with both options is the other UIApplicationDelegate notifications that the AppDelegate may receive, such as applicationWillResignActive: and applicationDidBecomeActive:. The library may need to handle notifications like that to properly maintain its UI. Must the AppDelegate pass each of these to the library when its UI is active?
Is there a better option 3 that I haven't thought of?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否考虑过设计 API 来接受
UIViewController
:这样,您的库就可以完全控制模态 UI 的呈现方式,并且还可以调用
-dismissViewControllerAnimated:
本身而不是依靠代表来这样做。不必费心传递
-applicationWillResignActive:
等。只需在库类中注册底层通知UIApplicationWillResignActiveNotification
等即可。Have you considered designing your API to accept a
UIViewController
:That way, your library has full control over how the modal UI is presented, and can also call
-dismissViewControllerAnimated:
itself rather than relying on the delegate to do so.Don't bother to pass around
-applicationWillResignActive:
etc. Simply register for the underlying notificationsUIApplicationWillResignActiveNotification
etc. in your library class.我是这样做的:
在静态库中创建 UIViewController 以及以编程方式需要的所有内容视图(因为您无法轻松地在 iOS 上制作框架,因此无法轻松捆绑资源):
然后使用以下命令显示它
这是从工作静态库剪切并粘贴的它已嵌入到两个不同的 iOS 应用程序中,并且似乎在这两个应用程序中都运行良好。可能有一些边缘情况没有涵盖,但我还没有遇到:)
Here's how I do it:
In your static library create your UIViewController and all the content views that you need programmatically (since you can't easily make Frameworks on iOS you can't easily bundle resources):
then display it with
This is cut and pasted from a working static library that's been embedded into two different iOS applications and seems to work well in both. There may be edge cases that this doesn't cover, but I haven't hit them yet :)
使用块而不是委托。完成后,您的视图应该调用存储在属性中的提供的
dismissBlock
,并且调用者可以从该块执行其需要执行的操作。有需要传回的数据吗?根据需要,将其作为块的参数或将其放入可从视图控制器访问的对象的属性中。如果您有需要存储以响应事件的状态,请记录该状态并提供一种将该信息保存到某些数据中并从数据块恢复 UI 的方法。调用者可以按照自己的意愿进行处理。
UI 的精确显示方式应由客户端应用程序决定,但通过规定 UI 确实必须以模态方式显示,您就可以充分限制其环境,从而不必过多担心主机环境。
Use blocks instead of a delegate. Your view should call a provided
dismissBlock
stored in a property when it's done, and the caller can do what it needs to do from that block. Have data you need to pass back? Make it an argument of the block or put it in a property of an object accessible from your view controller, as appropriate.If you have state that needs storing in response to an event, document that and provide a way to save off that info into some data and restore the UI from a block of data. The caller can handle that as they wish.
Precisely how the UI is displayed modally should be up to the client application, but by providing that the UI must indeed be displayed modally, you limit its environment enough that you shouldn't have to worry too much about the host environment.