WatchOS:在基于页面的导航中插入页面
WatchOS: Inserting pages in page-based navigation
我正在使用 -[WKInterfaceController presentControllerWithNames:contexts:]
以模态方式呈现一组动态创建的页面。有时我想在页面集中插入可见的页面。这是可能的,还是一旦可见就固定了一组页面?
我设计了一个方法来实现这个,但是很麻烦。更好的解决方案将是一个相当大的改进。
- 页面组中的每个
WKInterfaceController
都有一个 UUID
属性,它使用其上下文分配并存储在 awakeWithContext:
期间
- 显示页面组的
WKInterfaceController
在显示之前保留 WKInterfaceController
名称和上下文的数组
- 当其中一个页面需要 insert/delete 个页面时,它会向当前
WKInterfaceController
发回通知
- 呈现
WKInterfaceController
在其保留的 WKInterfaceController
名称和上下文数组中进行所需的更改
- 呈现
WKInterfaceController
关闭当前页面组,然后使用更新的 name/context 数组重新呈现它们
- 呈现
WKInterfaceController
发布一个通知,所有页面都会观察到该通知,包括新页面的 UUID
作为通知对象。通知会触发页面根据通知对象中发送的页面检查自己的 UUID
。如果通知匹配,则该接口控制器调用 becomeCurrentPage
我还没有实际测试过,但这是我能想到的唯一可行的方法。但这会很丑陋,因为您会看到当前页面消失,然后第一页出现,然后新页面以动画形式出现。从用户体验的角度来看不是很好,但我想不出任何其他方法,因为 Apple 没有给我们任何插入页面的方法。
这是我为此设计的解决方案。
/*
MyInterfaceController - class within the set of pages
*/
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
NSDictionary *dict = (NSDictionary*)context;
self.uuid = [dict valueForKey:@"uuid"];
self.jumpuuid = [dict valueForKey:@"jumpuuid"];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkBecomeCurrentPage:) name:@"checkBecomeCurrentPage" object:nil];
}
- (void)checkBecomeCurrentPage:(NSNotification*)notification {
NSString *checkUUID = (NSString*)notification.object;
if ([self.uuid isEqualToString:checkUUID]) {
[self becomeCurrentPage];
}
}
- (void)didAppear {
[super didAppear];
if (self.jumpuuid) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"checkBecomeCurrentPage" object:self.jumpuuid];
}
}
- (IBAction)addPageButtonAction {
[[NSNotificationCenter defaultCenter] postNotificationName:@"addPageNotification" object:self];
}
#warning Populate this with the names and contexts for the set of pages when initially displaying them. It is used for inserting pages later
+ (NSMutableDictionary*)namesAndContextsForCurrentlyDisplayedPage {
static NSMutableDictionary *dict = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dict = [NSMutableDictionary dictionary];
});
return dict;
}
+ (void)addPageWithPresentingController:(WKInterfaceController *)presentingController requestingInterfaceController:(MyInterfaceController *)requestingInterfaceController {
NSMutableArray *contexts = [[[MyInterfaceController namesAndContextsForCurrentlyDisplayedPages] objectForKey:@"contexts"] mutableCopy];
NSInteger requestingInterfaceControllerIndex = -1;
for (NSDictionary *dict in contexts) {
if ([[dict valueForKey:@"uuid"] isEqualToString:requestingInterfaceController.uuid]) {
requestingInterfaceControllerIndex = [contexts indexOfObject:dict];
}
}
if (requestingSetInterfaceControllerIndex == -1) {
#warning Display an error that the position of the current page could not be established
}
else {
NSInteger insertIndex = requestingInterfaceControllerIndex + 1;
NSMutableArray *names = [[[MyInterfaceController namesAndContextsForCurrentlyDisplayedPages] objectForKey:@"names"] mutableCopy];
[names insertObject:@"MyInterfaceController" atIndex:insertIndex];
NSString *newUUID = [[NSUUID UUID] UUIDString];
NSDictionary *newDict = @{@"uuid": newUUID};
[contexts insertObject:newdict atIndex:insertIndex];
NSMutableDictionary *firstDict = [contexts.firstObject mutableCopy];
[firstDict setValue:newUUID forKey:@"jumpuuid"];
[contexts replaceObjectAtIndex:0 withObject:firstDict];
[[MyInterfaceController namesAndContextsForCurrentlyDisplayedPages] setValue:names forKey:@"names"];
[[MyInterfaceController namesAndContextsForCurrentlyDisplayedPages] setValue:contexts forKey:@"contexts"];
[presentingController dismissController];
[presentingController presentControllerWithNames:names contexts:contexts];
}
}
-
/*
MyParentInterfaceController - the controller which originally presented the set of pages
*/
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addPage:) name:@"addPageNotification" object:nil];
}
- (void)addPage:(NSNotification*)notification {
[MyInterfaceController addPageWithPresentingController:self requestingInterfaceController:notification.object];
}
我正在使用 -[WKInterfaceController presentControllerWithNames:contexts:]
以模态方式呈现一组动态创建的页面。有时我想在页面集中插入可见的页面。这是可能的,还是一旦可见就固定了一组页面?
我设计了一个方法来实现这个,但是很麻烦。更好的解决方案将是一个相当大的改进。
- 页面组中的每个
WKInterfaceController
都有一个UUID
属性,它使用其上下文分配并存储在awakeWithContext:
期间
- 显示页面组的
WKInterfaceController
在显示之前保留WKInterfaceController
名称和上下文的数组 - 当其中一个页面需要 insert/delete 个页面时,它会向当前
WKInterfaceController
发回通知
- 呈现
WKInterfaceController
在其保留的WKInterfaceController
名称和上下文数组中进行所需的更改 - 呈现
WKInterfaceController
关闭当前页面组,然后使用更新的 name/context 数组重新呈现它们 - 呈现
WKInterfaceController
发布一个通知,所有页面都会观察到该通知,包括新页面的UUID
作为通知对象。通知会触发页面根据通知对象中发送的页面检查自己的UUID
。如果通知匹配,则该接口控制器调用becomeCurrentPage
我还没有实际测试过,但这是我能想到的唯一可行的方法。但这会很丑陋,因为您会看到当前页面消失,然后第一页出现,然后新页面以动画形式出现。从用户体验的角度来看不是很好,但我想不出任何其他方法,因为 Apple 没有给我们任何插入页面的方法。
这是我为此设计的解决方案。
/*
MyInterfaceController - class within the set of pages
*/
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
NSDictionary *dict = (NSDictionary*)context;
self.uuid = [dict valueForKey:@"uuid"];
self.jumpuuid = [dict valueForKey:@"jumpuuid"];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkBecomeCurrentPage:) name:@"checkBecomeCurrentPage" object:nil];
}
- (void)checkBecomeCurrentPage:(NSNotification*)notification {
NSString *checkUUID = (NSString*)notification.object;
if ([self.uuid isEqualToString:checkUUID]) {
[self becomeCurrentPage];
}
}
- (void)didAppear {
[super didAppear];
if (self.jumpuuid) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"checkBecomeCurrentPage" object:self.jumpuuid];
}
}
- (IBAction)addPageButtonAction {
[[NSNotificationCenter defaultCenter] postNotificationName:@"addPageNotification" object:self];
}
#warning Populate this with the names and contexts for the set of pages when initially displaying them. It is used for inserting pages later
+ (NSMutableDictionary*)namesAndContextsForCurrentlyDisplayedPage {
static NSMutableDictionary *dict = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dict = [NSMutableDictionary dictionary];
});
return dict;
}
+ (void)addPageWithPresentingController:(WKInterfaceController *)presentingController requestingInterfaceController:(MyInterfaceController *)requestingInterfaceController {
NSMutableArray *contexts = [[[MyInterfaceController namesAndContextsForCurrentlyDisplayedPages] objectForKey:@"contexts"] mutableCopy];
NSInteger requestingInterfaceControllerIndex = -1;
for (NSDictionary *dict in contexts) {
if ([[dict valueForKey:@"uuid"] isEqualToString:requestingInterfaceController.uuid]) {
requestingInterfaceControllerIndex = [contexts indexOfObject:dict];
}
}
if (requestingSetInterfaceControllerIndex == -1) {
#warning Display an error that the position of the current page could not be established
}
else {
NSInteger insertIndex = requestingInterfaceControllerIndex + 1;
NSMutableArray *names = [[[MyInterfaceController namesAndContextsForCurrentlyDisplayedPages] objectForKey:@"names"] mutableCopy];
[names insertObject:@"MyInterfaceController" atIndex:insertIndex];
NSString *newUUID = [[NSUUID UUID] UUIDString];
NSDictionary *newDict = @{@"uuid": newUUID};
[contexts insertObject:newdict atIndex:insertIndex];
NSMutableDictionary *firstDict = [contexts.firstObject mutableCopy];
[firstDict setValue:newUUID forKey:@"jumpuuid"];
[contexts replaceObjectAtIndex:0 withObject:firstDict];
[[MyInterfaceController namesAndContextsForCurrentlyDisplayedPages] setValue:names forKey:@"names"];
[[MyInterfaceController namesAndContextsForCurrentlyDisplayedPages] setValue:contexts forKey:@"contexts"];
[presentingController dismissController];
[presentingController presentControllerWithNames:names contexts:contexts];
}
}
-
/*
MyParentInterfaceController - the controller which originally presented the set of pages
*/
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addPage:) name:@"addPageNotification" object:nil];
}
- (void)addPage:(NSNotification*)notification {
[MyInterfaceController addPageWithPresentingController:self requestingInterfaceController:notification.object];
}