Форум программистов, компьютерный форум CyberForum.ru

Objective-C

Войти
Регистрация
Восстановить пароль
 
sp1derok
1 / 1 / 0
Регистрация: 04.02.2015
Сообщений: 18
#1

Работа с "вкладками" в самодельном браузере - Objective-C

24.03.2015, 19:16. Просмотров 922. Ответов 2
Метки нет (Все метки)

Помогите разобраться, не могу уже понять куда копать.
В общем ситуация такая, когда открываю ссылку в новой вкладке все ок. Потому закрываю ее и открываю другую ссылку, она тоже открывается но заголовок вкладки остается от закрытой вкладки. Если меняю фокус на первую вкладку и возвращаюсь обратно, то на вкладке уже отображается не та ссылка что я открыл последней, а та что я открыл и закрыл первой.
Если сильно намудрил с описанием (не знаю как это правильно описать), прикладываю гифку как это происходит :
Скрин

Вот сам код :
.h
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#import <Cocoa/Cocoa.h>
#import <MMTabBarView/MMTabBarView.h>
#import "ERBrowser.h"
@interface ERBrowserWindowController : NSWindowController <NSTextFieldDelegate, NSToolbarDelegate, MMTabBarViewDelegate, NSMenuDelegate>
{
    IBOutlet NSTabView *tabView;
    IBOutlet MMTabBarView *tabBarControl;
    IBOutlet NSSearchField *searchField;
    IBOutlet NSView *mainView;
    NSMutableArray *browserViews;
}
- (MMTabBarView *)tabBarControl;
- (ERBrowser *)addWebView:(NSURL *)url;
@end
.m
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
- (ERBrowser *)addWebView:(NSURL *)url{
    for (NSView *view in browserViews)
       [view setHidden:true];
 
    ERTabModel *tabModel = [[ERTabModel alloc] init];
    NSTabViewItem *tabItem = [[NSTabViewItem alloc] initWithIdentifier:tabModel];
    [tabView addTabViewItem:tabItem];
    [tabView selectTabViewItem:tabItem];
 
    ERBrowser *browserView = [[ERBrowser alloc] initWithFrame:mainView.frame];
    [browserView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
    [mainView addSubview:browserView];
    [browserViews addObject:browserView];
    [browserView setUIDelegate:self];
    [browserView setFrameLoadDelegate:self];
 
    if (url)
        [[browserView mainFrame] loadRequest:[NSURLRequest requestWithURL:url]];
 
    return browserView;
}
- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
{
   NSTabViewItem *tabViewItem = nil;
    for (int i = 0; i < [browserViews count]; i++)
        if (browserViews[i] == sender)
            tabViewItem = [tabView tabViewItemAtIndex:i];
    [searchField setStringValue:@""];
    [tabViewItem setLabel:[[frame webView] stringByEvaluatingJavaScriptFromString:@"document.title"]];
}
 
- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
{
    return [self addWebView:[request URL]];
}
// MMTabBarVievDelegate
- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem
{
    NSInteger index = [aTabView indexOfTabViewItem:tabViewItem];
    if ([browserViews count] > index)
    {
        for (NSView *view in browserViews)
          [view setHidden:true];
        ERBrowser *browserView = browserViews[index];
        [browserView setHidden:false];
        [searchField setStringValue:@""];
        [tabViewItem setLabel:[browserView stringByEvaluatingJavaScriptFromString:@"document.title"]];
    }
}
- (void)tabView:(NSTabView *)aTabView didCloseTabViewItem:(NSTabViewItem *)tabViewItem
{
    NSInteger index = [aTabView indexOfTabViewItem:tabViewItem];
    if ([browserViews count] > index)
    {
        [browserViews removeObjectAtIndex:index];
    }
}
ERBrowser.h
Objective-C
1
2
3
4
5
#import <WebKit/WebKit.h>
 
@interface ERBrowser : WebView
 
@end
ERBrowser.m
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#import "ERBrowser.h"
 
@implementation ERBrowser
 
- (id)initWithFrame:(NSRect)frame
{
    if (self = [super initWithFrame:frame])
    {
        [self setCustomUserAgent:@"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36"];
        
        [self setShouldUpdateWhileOffscreen:true];
    }
    return self;
}
 
@end
B Xcode ругается на :

2015-03-23 19:11:24.469 ERClient[54239:14312957] * WebKit discarded an uncaught exception in the webView:didReceiveTitle:forFrame: delegate: * -[__NSArrayM objectAtIndex:]: index 3 beyond bounds [0 .. 1]

Я пока еще очень плохо во всем этом разбираюсь, перекопал этот код уже кучу раз, так и не смог понять почему так происходит.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.03.2015, 19:16     Работа с "вкладками" в самодельном браузере
Посмотрите здесь:
Objective-C Приведение типов, или как избавиться от "Warning"
Objective-C Объясните, что это: "static const uint32_t collisionCategory = 0x1 << 0"?
Не создается объект. Ошибка "autorelease called without pool for object of class" Objective-C
Thread 1: Program received signal "SIGABRT" Objective-C
Ошибка "SIGABRT" в Xcode(Objective-C) Objective-C
Objective-C Хранение значения переменной "онлайн"
Objective-C Игра типа "Tower Bloxx"
Ошибка: "Необъявленная переменная m" Objective-C
Objective-C Сообщение "Value stored to . during its initialization"
Objective-C Первые "шаги" в objective c
Objective-C "ездящий" View
Objective-C Как переключаться между внутренними вкладками свайпом слева направо?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
25.03.2015, 07:37     Работа с "вкладками" в самодельном браузере #2
Выход за границу массива тут:
Objective-C
1
2
3
for (int i = 0; i < [browserViews count]; i++)
        if (browserViews[i] == sender)
            tabViewItem = [tabView tabViewItemAtIndex:i];
sp1derok
1 / 1 / 0
Регистрация: 04.02.2015
Сообщений: 18
27.03.2015, 13:11  [ТС]     Работа с "вкладками" в самодельном браузере #3
Сегодня снова копался как удаляются объекты из NSMutableArray. Не смотря на то что я задаю удалять тот объект что соответствует активной вкладке, все равно удаляется первый объект в списке. То есть получается корректное закрытие вкладки только при условии если я закрываю первую вкладку.
Прочитал кучу статей по поводу NSMutableArray и метода removeObjectAtIndex, но так и не нашел почему так происходит, не смотря на то что я указал условия, какой именно объект удалять

Добавлено через 2 часа 45 минут
Мне подсказали что использовать нужно не didCloseTabViewItem, а willCloseTabViewItem для того что находился нужный объект и удалялся. Я проверил и действительно это так.
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
{
    NSLog(@"didReceiveTitle!");
   NSTabViewItem *tabViewItem = nil;
    
    for (int i = 0; i < [browserViews count]; i++)
        if (browserViews[i] == sender)
            tabViewItem = [tabView tabViewItemAtIndex:i];
    
    [searchField setStringValue:@""];
    [tabViewItem setLabel:[[frame webView] stringByEvaluatingJavaScriptFromString:@"document.title"]];
}
 
- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
{
    NSLog(@"createWebViewWithRequest!");
    return [self addWebView:[request URL]];
 
}
- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem {
    NSUInteger index = [aTabView indexOfTabViewItem:tabViewItem];
    NSLog(@"didSelectTabViewItem Индекс %ld", (long)index);
    
    if ([browserViews count] > index)
    {
        for (NSView *view in browserViews)
            [view setHidden:true];
        ERBrowser *browserView = browserViews[index];
        [browserView setHidden:false];
        NSLog(@"Индекс при изменении фокуса по табам %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 Индекс %ld", (long)index);
   if ([browserViews count] > index)
   {
        [browserViews removeObjectAtIndex:index];
        NSLog(@"%@" @"%ld", browserViews, (long)index);
   }
}
Теперь удаляется нормально. Но по сути проблема осталась. Получается так что вкладка номер 1 получается индекс объекта 0, а вкладка номер 2 индекс объекта 1.
В логах я вижу что все корректно удаляется. Но после удаления вкладки номер 2, остается вкладка номер 1 не со своим содержимым, а с содержимым только что закрытой вкладки.
Программа загрузилась и открылась дефаултная вкладка с google.com :
2015-03-26 16:53:53.500 ERClient[88528:25733277] didSelectTabViewItem Индекс 0
2015-03-26 16:53:53.639 ERClient[88528:25733277] ("<ERBrowser: 0x6080001237a0>")
2015-03-26 16:53:54.996 ERClient[88528:25733277] didReceiveTitle!
Открываю gmail в новой вкладке :
2015-03-26 16:55:41.454 ERClient[88528:25733277] createWebViewWithRequest!
2015-03-26 16:55:41.455 ERClient[88528:25733277] didSelectTabViewItem Индекс 1
2015-03-26 16:55:41.460 ERClient[88528:25733277] ("<ERBrowser: 0x6080001237a0>",
"<ERBrowser: 0x608000127bc0>")
2015-03-26 16:55:42.876 ERClient[88528:25733277] didReceiveTitle!
2015-03-26 16:55:46.300 ERClient[88528:25733277] didReceiveTitle!
2015-03-26 16:55:47.051 ERClient[88528:25733277] didReceiveTitle! - вот это меня смутило, почему это действие произошло 3 раза, а не как должно быть 2. Ведь вкладок всего 2 на данный момент.
На данный момент открыта вкладка 2 с индексом 1, я перевожу фокус на первую с ондексом 0, а потом возвращаю обратно:
2015-03-26 16:58:13.042 ERClient[88528:25733277] didSelectTabViewItem Индекс 0
2015-03-26 16:58:13.046 ERClient[88528:25733277] Индекс при изменении фокуса по табам 0
2015-03-26 16:58:15.607 ERClient[88528:25733277] didSelectTabViewItem Индекс 1
2015-03-26 16:58:15.608 ERClient[88528:25733277] Индекс при изменении фокуса по табам 1
Теперь я закрываю вкладку 2 с индексом 1:
2015-03-26 16:59:27.955 ERClient[88528:25733277] willCloseTabViewItem Индекс 1
2015-03-26 16:59:27.955 ERClient[88528:25733277] ("<ERBrowser: 0x6080001237a0>")1
2015-03-26 16:59:27.956 ERClient[88528:25733277] didSelectTabViewItem Индекс 0
2015-03-26 16:59:27.956 ERClient[88528:25733277] Индекс при изменении фокуса по табам 0

У меня остается 1 вкладка, на которой тайтл верный как и при старте программы, а содержимое от вкладки которую я только что закрыл.

Добавлено через 19 часов 4 минуты
В общем проблема возникла по той причине что у меня еще очень мало опыта и знаний во всем этом деле.
Когда я удалял объект из NSMutableArray все проходило хорошо, но загруженная WebView оставалась.
Нужно было добавить
Objective-C
1
[browserView removeFromSuperview];
и тогда все объекты связанные с данной вкладкой, начали удаляться корректно.
Возможно кому то пригодится, если будите делать браузер с вкладками или еще что то подобное

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (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];
 
   }
}
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru