NSMutableArray removeObjectAtIndex 和 NSTabView
NSMutableArray removeObjectAtIndex and NSTabView
我的程序是一个带有 MMTabBarView 的网络浏览器。
关闭选项卡的问题通过查看 log.I 已从 NSMutableArray * browserViews;
中看到在 willCloseTabViewItem 中调用 [browserViews removeObjectAtIndex: index];
时关闭无效元素
这是代码:
.h
{
IBOutlet NSTabView *tabView;
IBOutlet MMTabBarView *tabBarControl;
IBOutlet NSSearchField *searchField;
IBOutlet NSView *mainView;
NSMutableArray *browserViews;
}
- (MMTabBarView *)tabBarControl;
- (ERBrowser *)addWebView:(NSURL *)url;
- (void)addDefaultTabs;
.m
- (id)initWithWindow:(NSWindow *)window
{
if (self = [super initWithWindow:window])
{
browserViews = [[NSMutableArray alloc] init];
}
return self;
}
- (void)windowDidLoad{
[super windowDidLoad];
for (NSTabViewItem *item in [tabView tabViewItems])
[tabView removeTabViewItem:item];
[tabView setAutoresizesSubviews:true];
[searchField setDelegate:self];
[tabBarControl setDelegate:self];
}
- (ERBrowser *)addWebView:(NSURL *)url{
for (NSView *view in browserViews)
[view setHidden:false];
ERTabModel *tabModel = [[ERTabModel alloc] init];
NSTabViewItem *tabViewItem = [[NSTabViewItem alloc] initWithIdentifier:tabModel];
[tabView addTabViewItem:tabViewItem];
[tabView selectTabViewItem:tabViewItem];
ERBrowser *browserView = [[ERBrowser alloc] initWithFrame:mainView.frame];
[browserView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[mainView addSubview:browserView];
[browserViews addObject:browserView];
[browserView setUIDelegate:self];
[browserView setFrameLoadDelegate:self];
NSLog(@"%@", browserViews);
if (url)
[[browserView mainFrame] loadRequest:[NSURLRequest requestWithURL:url]];
return browserView;
}
- (void)addDefaultTabs {
[self addWebView:[NSURL URLWithString:@"http://google.com"]];
}
- (MMTabBarView *)tabBarControl {
return tabBarControl;
}
// Method called when webView javascript requests new window with request
- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
{
NSLog(@"createWebViewWithRequest!");
return [self addWebView:[request URL]];
}
// MMTabBarVievDelegate
- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem {
NSUInteger index = [aTabView indexOfTabViewItem:tabViewItem];
NSLog(@"didSelectTabViewItem Index %ld", (long)index);
if ([browserViews count] > index)
{
for (NSView *view in browserViews)
[view setHidden:true];
ERBrowser *browserView = browserViews[index];
[browserView setHidden:false];
NSLog(@"Index change focus tab %ld", (long)index);
[searchField setStringValue:@""];
[tabViewItem setLabel:[browserView stringByEvaluatingJavaScriptFromString:@"document.title"]];
}
}
- (void)tabView:(NSTabView *)aTabView willCloseTabViewItem:(NSTabViewItem *)tabViewItem
{
NSUInteger index = [aTabView indexOfTabViewItem:[tabView selectedTabViewItem]];
NSLog(@"willCloseTabViewItem Index %ld", (long)index);
if ([browserViews count] > index)
{
[browserViews removeObjectAtIndex:index];
NSLog(@"%@" @"%ld", browserViews, (long)index);
}
}
并记录:
程序加载默认Tab google.com:
2015-03-26 17:51:57.634 ERClient[89171:26065490] didSelectTabViewItem
Index 0
2015-03-26 17:51:59.030 ERClient[89171:26065490] (ERBrowser:
0x600000124060)
2015-03-26 17:52:02.278 ERClient[89171:26065490] didReceiveTitle!
Gmail 在新标签页中打开:
2015-03-26 17:53:51.994 ERClient[89171:26065490]
createWebViewWithRequest!
2015-03-26 17:53:51.995 ERClient[89171:26065490] didSelectTabViewItem
Index 1
2015-03-26 17:53:52.035 ERClient[89171:26065490] (ERBrowser:
0x600000124060, ERBrowser: 0x600000121cc0)
2015-03-26 17:53:53.987 ERClient[89171:26065490] didReceiveTitle!
2015-03-26 17:53:56.451 ERClient[89171:26065490] didReceiveTitle!
2015-03-26 17:53:59.003 ERClient[89171:26065490] didReceiveTitle! -
I do not understand why this happens 3 times instead of 2
将焦点放在索引为 1 的 Tab 2 上,我将焦点更改为第一个 Tab 索引 0,然后 return 返回:
2015-03-26 17:57:56.384 ERClient[89171:26065490] didSelectTabViewItem
Index 0
2015-03-26 17:57:56.477 ERClient[89171:26065490] Index change focus
tab 0
2015-03-26 17:57:58.206 ERClient[89171:26065490] didSelectTabViewItem
Index 1
2015-03-26 17:57:58.207 ERClient[89171:26065490] Index change focus
tab 1
现在我关闭索引为 1 的选项卡 2:
2015-03-26 17:58:55.691 ERClient[89171:26065490] willCloseTabViewItem
Index 1
2015-03-26 17:58:55.691 ERClient[89171:26065490] (ERBrowser:
0x600000124060) 1
2015-03-26 17:58:55.692 ERClient[89171:26065490] didSelectTabViewItem
Index 0
2015-03-26 17:58:55.693 ERClient[89171:26065490] Index change focus
tab 0
事实证明,打开带有有效标题的选项卡 1,但内容保留在选项卡 2 中:
如果我打开另一个Tab,也会显示gmail
告诉我如何解决它或在哪里阅读为什么会发生这种情况
问题已自行解决。
问题是由于我在编程方面有一点经验。
现在我将描述为什么不工作。
当您从 NSMutableArray 中删除一个对象时,加载页面仍然保留 WebView 对象。有必要添加 [browserView removeFromSuperview];
代码如下:
- (void)tabView:(NSTabView *)aTabView willCloseTabViewItem:(NSTabViewItem *)tabViewItem
{
NSUInteger index = [aTabView indexOfTabViewItem:[tabView selectedTabViewItem]];
if ([browserViews count] > index)
{
ERBrowser *browserView = browserViews[index];
[browserViews removeObjectAtIndex:index];
[browserView removeFromSuperview];
}
}
也许将来有人会用得上创建一个带有标签栏的网络浏览器
此外,您应该根据文档调用 super 方法:
/* Implemented methods from NSTabViewDelegate. These require a call to super if overriden by a subclass. */
- (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(nullable NSTabViewItem *)tabViewItem NS_REQUIRES_SUPER;
- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(nullable NSTabViewItem *)tabViewItem NS_REQUIRES_SUPER;
- (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(nullable NSTabViewItem *)tabViewItem NS_REQUIRES_SUPER;
我的程序是一个带有 MMTabBarView 的网络浏览器。
关闭选项卡的问题通过查看 log.I 已从 NSMutableArray * browserViews;
中看到在 willCloseTabViewItem 中调用 [browserViews removeObjectAtIndex: index];
时关闭无效元素
这是代码:
.h
{
IBOutlet NSTabView *tabView;
IBOutlet MMTabBarView *tabBarControl;
IBOutlet NSSearchField *searchField;
IBOutlet NSView *mainView;
NSMutableArray *browserViews;
}
- (MMTabBarView *)tabBarControl;
- (ERBrowser *)addWebView:(NSURL *)url;
- (void)addDefaultTabs;
.m
- (id)initWithWindow:(NSWindow *)window
{
if (self = [super initWithWindow:window])
{
browserViews = [[NSMutableArray alloc] init];
}
return self;
}
- (void)windowDidLoad{
[super windowDidLoad];
for (NSTabViewItem *item in [tabView tabViewItems])
[tabView removeTabViewItem:item];
[tabView setAutoresizesSubviews:true];
[searchField setDelegate:self];
[tabBarControl setDelegate:self];
}
- (ERBrowser *)addWebView:(NSURL *)url{
for (NSView *view in browserViews)
[view setHidden:false];
ERTabModel *tabModel = [[ERTabModel alloc] init];
NSTabViewItem *tabViewItem = [[NSTabViewItem alloc] initWithIdentifier:tabModel];
[tabView addTabViewItem:tabViewItem];
[tabView selectTabViewItem:tabViewItem];
ERBrowser *browserView = [[ERBrowser alloc] initWithFrame:mainView.frame];
[browserView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[mainView addSubview:browserView];
[browserViews addObject:browserView];
[browserView setUIDelegate:self];
[browserView setFrameLoadDelegate:self];
NSLog(@"%@", browserViews);
if (url)
[[browserView mainFrame] loadRequest:[NSURLRequest requestWithURL:url]];
return browserView;
}
- (void)addDefaultTabs {
[self addWebView:[NSURL URLWithString:@"http://google.com"]];
}
- (MMTabBarView *)tabBarControl {
return tabBarControl;
}
// Method called when webView javascript requests new window with request
- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
{
NSLog(@"createWebViewWithRequest!");
return [self addWebView:[request URL]];
}
// MMTabBarVievDelegate
- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem {
NSUInteger index = [aTabView indexOfTabViewItem:tabViewItem];
NSLog(@"didSelectTabViewItem Index %ld", (long)index);
if ([browserViews count] > index)
{
for (NSView *view in browserViews)
[view setHidden:true];
ERBrowser *browserView = browserViews[index];
[browserView setHidden:false];
NSLog(@"Index change focus tab %ld", (long)index);
[searchField setStringValue:@""];
[tabViewItem setLabel:[browserView stringByEvaluatingJavaScriptFromString:@"document.title"]];
}
}
- (void)tabView:(NSTabView *)aTabView willCloseTabViewItem:(NSTabViewItem *)tabViewItem
{
NSUInteger index = [aTabView indexOfTabViewItem:[tabView selectedTabViewItem]];
NSLog(@"willCloseTabViewItem Index %ld", (long)index);
if ([browserViews count] > index)
{
[browserViews removeObjectAtIndex:index];
NSLog(@"%@" @"%ld", browserViews, (long)index);
}
}
并记录: 程序加载默认Tab google.com:
2015-03-26 17:51:57.634 ERClient[89171:26065490] didSelectTabViewItem Index 0
2015-03-26 17:51:59.030 ERClient[89171:26065490] (ERBrowser: 0x600000124060)
2015-03-26 17:52:02.278 ERClient[89171:26065490] didReceiveTitle!
Gmail 在新标签页中打开:
2015-03-26 17:53:51.994 ERClient[89171:26065490] createWebViewWithRequest!
2015-03-26 17:53:51.995 ERClient[89171:26065490] didSelectTabViewItem Index 1
2015-03-26 17:53:52.035 ERClient[89171:26065490] (ERBrowser: 0x600000124060, ERBrowser: 0x600000121cc0)
2015-03-26 17:53:53.987 ERClient[89171:26065490] didReceiveTitle!
2015-03-26 17:53:56.451 ERClient[89171:26065490] didReceiveTitle!
2015-03-26 17:53:59.003 ERClient[89171:26065490] didReceiveTitle! - I do not understand why this happens 3 times instead of 2
将焦点放在索引为 1 的 Tab 2 上,我将焦点更改为第一个 Tab 索引 0,然后 return 返回:
2015-03-26 17:57:56.384 ERClient[89171:26065490] didSelectTabViewItem Index 0
2015-03-26 17:57:56.477 ERClient[89171:26065490] Index change focus tab 0
2015-03-26 17:57:58.206 ERClient[89171:26065490] didSelectTabViewItem Index 1
2015-03-26 17:57:58.207 ERClient[89171:26065490] Index change focus tab 1
现在我关闭索引为 1 的选项卡 2:
2015-03-26 17:58:55.691 ERClient[89171:26065490] willCloseTabViewItem Index 1
2015-03-26 17:58:55.691 ERClient[89171:26065490] (ERBrowser: 0x600000124060) 1
2015-03-26 17:58:55.692 ERClient[89171:26065490] didSelectTabViewItem Index 0
2015-03-26 17:58:55.693 ERClient[89171:26065490] Index change focus tab 0
事实证明,打开带有有效标题的选项卡 1,但内容保留在选项卡 2 中:
如果我打开另一个Tab,也会显示gmail 告诉我如何解决它或在哪里阅读为什么会发生这种情况
问题已自行解决。
问题是由于我在编程方面有一点经验。
现在我将描述为什么不工作。
当您从 NSMutableArray 中删除一个对象时,加载页面仍然保留 WebView 对象。有必要添加 [browserView removeFromSuperview];
代码如下:
- (void)tabView:(NSTabView *)aTabView willCloseTabViewItem:(NSTabViewItem *)tabViewItem
{
NSUInteger index = [aTabView indexOfTabViewItem:[tabView selectedTabViewItem]];
if ([browserViews count] > index)
{
ERBrowser *browserView = browserViews[index];
[browserViews removeObjectAtIndex:index];
[browserView removeFromSuperview];
}
}
也许将来有人会用得上创建一个带有标签栏的网络浏览器
此外,您应该根据文档调用 super 方法:
/* Implemented methods from NSTabViewDelegate. These require a call to super if overriden by a subclass. */
- (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(nullable NSTabViewItem *)tabViewItem NS_REQUIRES_SUPER;
- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(nullable NSTabViewItem *)tabViewItem NS_REQUIRES_SUPER;
- (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(nullable NSTabViewItem *)tabViewItem NS_REQUIRES_SUPER;