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

Objective-C

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

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

24.03.2015, 19:16. Просмотров 946. Ответов 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]

Я пока еще очень плохо во всем этом разбираюсь, перекопал этот код уже кучу раз, так и не смог понять почему так происходит.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.03.2015, 19:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Работа с "вкладками" в самодельном браузере (Objective-C):

Муки выбора: core data или работа "напрямую" с sqlite - Программирование iOS
Здравствуйте! Я новичок в разработке под osx и ios, но так как база на сях и плюсах была (когда-то давно), то идет это дело у меня довольно...

Сервер / Game Center для онлайн игры "Шашки" - Программирование iOS
Здравствуйте уважаемые пользователи форума. Реализовал ли кто-то из вас онлайн игры под ios? Планирую заказать разработку онлайн игры...

Нужна загрузка "даты" с RSS | iOS | Xcode - Программирование iOS
Здравствуйте! У меня установлены 2 библиотеки ( RSS Parser и AFNetworking)! Мне нужна загрузка ДАТЫ в ТАБЛИЦУ используя RSS.

Как создать кнопку "like" (например, фейсбуковский) на UIView? - Программирование iOS
я создал (пустой) проект (view-based application). теперь хочу прикрепить на экран facebookLike кнопочку. затем приложение должно спросить...

Приведение типов, или как избавиться от "Warning" - Objective-C
Добрый день господа! Поможите привести типы в порядок, в Delphi есть чудо операторы IntToStr, StrToFloat, и проч. Ну а Xcode при таком...

Не создается объект. Ошибка "autorelease called without pool for object of class" - Objective-C
Здравствуйте. Почему не создается объект Rect? #import &lt;Foundation/Foundation.h&gt; @interface Rect : NSObject &lt;NSCopying&gt; { ...

2
zulkis
682 / 609 / 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];
0
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];
 
   }
}
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.03.2015, 13:11
Привет! Вот еще темы с ответами:

Объясните, что это: "static const uint32_t collisionCategory = 0x1 << 0"? - Objective-C
Встретил в одном туториале по SpriteKit следующую строчку static const uint32_t projectileCategory = 0x1 &lt;&lt; 0; Подскажите пожалуйста...

Форма обратной связи, при нажатии "Отправить" качает PHP файл - Программирование iOS
Сделал форму обратной связи и при нажатии &quot;Отправить&quot; качает PHP файл, в чем загвоздка??? форма сделана на HTML5 и CSS3 без...

CoreGraphics, "стёрка" части изображения в transparent - Программирование iOS
Ребят, привет! Хочу проконсультироваться. Есть два UIImageView один поверх другого. Я хочу стереть часть верхнего изображения, чтобы...

Thread 1: Program received signal "SIGABRT" - Objective-C
Добрый вечер. Использую Кокос2Д. Мне надо чтобы спрайт генерировался каждые 2 секунды с позиции другого спрайта(арроу): Пытался...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

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