我有一个问题,我已经打了好几个星期了。请帮忙。我有一个iOS 7应用程序,其中包含导航栏视图,带有嵌入文本字段的视图(addressBarView)和Web视图。我正在实现WebScriptObject(我并不关心iTunes商店的可通行性),因此网页JavaScript可以触发Objective C方法。这很有效,直到我触发一个应该隐藏导航栏和地址栏的方法。
以下是视图......
......这是子视图的结构和弹簧......
加载网页时,会检查META
标记。如果他们说<meta http-equiv="hidenavbar" content="true">
或<meta http-equiv="hideaddressbar" content="true">
,则会触发下面的showHideNavBar
或showHideNavBar
方法。这些工作很棒。
现在这里没有
我不会厌倦你在WebScriptObject上的细节,但这是相对的代码段。
#pragma mark - webScript Bridge
+ (NSString *)webScriptNameForSelector:(SEL)sel {
// Naming rules can be found at:http://goo.gl/GAkziE
if (sel == @selector(showHideAddressBar::)) {return @"showHideAddressBar";} else
if (sel == @selector(showHideNavBar::)) {return @"showHideNavBar";}
}
因为所有UI更改都必须在主线程上完成,所以我这样做......
- (void)showHideNavBar:(BOOL)hide :(BOOL)animate {
NSDictionary *navBarOptions = @{@"hide": [NSString stringWithFormat:@"%hhd", hide],
@"animate": [NSString stringWithFormat:@"%hhd", animate]};
[self performSelectorOnMainThread:@selector(navBarState:) withObject:navBarOptions waitUntilDone:NO];
}
- (void)showHideAddressBar:(BOOL)hide :(BOOL)animate {
NSDictionary *adrBarOptions = @{@"hide": [NSString stringWithFormat:@"%hhd", hide],
@"animate": [NSString stringWithFormat:@"%hhd", animate]};
[self performSelectorOnMainThread:@selector(addressBarState:) withObject:adrBarOptions waitUntilDone:NO];
}
然后是非常时髦的东西。
- (void)navBarState:(NSDictionary *)navBarOptions {
float addressBarY = navBarHidden ? 20.0f : 0.0f;
BOOL animate = [navBarOptions[@"animate"] boolValue];
BOOL hide = [navBarOptions[@"hide"] boolValue];
float webViewY = addressBarY + (addressBarHidden ? 0.0f : 40.0f);
float webViewHeight = [self view].frame.size.height - webViewY;
self.navigationController.navigationBar.translucent = NO;
if (hide && !navBarHidden) {
navBarHidden = YES;
[self.navigationController setNavigationBarHidden:YES animated:animate];
}
else if (!hide && navBarHidden) {
navBarHidden = NO;
[self.navigationController setNavigationBarHidden:NO animated:animate];
}
CGRect rectAddrBar = self.addressBarView.frame;
rectAddrBar.origin.y = addressBarY;
self.addressBarView.frame = rectAddrBar;
CGRect rectWebView = self.webView.frame;
rectWebView.origin.y = webViewY;
rectWebView.size.height = webViewHeight;
self.webView.frame = rectWebView;
dispatch_async(dispatch_get_main_queue(), ^{
[self.view layoutSubviews];
});
}
- (void)addressBarState:(NSDictionary *)adrBarOptions {
float addressBarY = navBarHidden ? 20.0f : 0.0f;
// BOOL animate = [adrBarOptions[@"animate"] boolValue];
BOOL hide = [adrBarOptions[@"hide"] boolValue];
float webViewY = addressBarY + (addressBarHidden ? 0.0f : 40.0f);
float webViewHeight = [self view].frame.size.height - webViewY;
if (hide && addressBarHidden == NO) {
addressBarHidden = YES;
self.addressBarView.hidden = YES;
self.urlTextField.hidden = YES;
webViewY = addressBarY;
webViewHeight = [self view].frame.size.height - webViewY;
} else if (!hide && addressBarHidden == YES) {
addressBarHidden = NO;
self.addressBarView.hidden = NO;
self.urlTextField.hidden = NO;
webViewY = self.addressBarView.frame.size.height;
webViewHeight = [self view].frame.size.height - webViewY;
}
CGRect rectAddrBar = self.addressBarView.frame;
rectAddrBar.origin.y = addressBarY;
self.addressBarView.frame = rectAddrBar;
CGRect rectWebView = self.webView.frame;
rectWebView.origin.y = webViewY;
rectWebView.size.height = webViewHeight;
self.webView.frame = rectWebView;
dispatch_async(dispatch_get_main_queue(), ^{
[self.view layoutSubviews];
});
}
这是正常状态。
以下是使用META标记指令在网页加载时隐藏导航栏和地址栏以隐藏栏。
现在,当隐藏栏并且我离开页面并返回时我得到了这个。
我在这个屏幕截图中下拉了网页,以便您可以看到地址栏隐藏在导航栏后面
当我在视图更新点设置断点时,我看到正在使用主线程。
我尝试了很多模式来实现这一点。我尝试过不使用dispatch_async(崩溃的应用程序),使用layoutIfNeeded,layoutSubviews等。有没有人有解决方案?
答案 0 :(得分:1)
你知道,一个角色可以成就你的理智。启动显示/隐藏操作webScriptNameForSelector
的方法是一种类方法。我必须为我需要操作的UI元素创建实例变量。