2015-09-22 6 views
2

Я создаю приложение на основе теста, чтобы узнать больше о том, как они работают. Я хочу загрузить массив, который я сохранил ранее.Невозможно изменить stringValue из метки в классе Document (приложение на основе документов, Mac)

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError 
{ 
    NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
    NSArray *array = [string componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; 

    documentTitle.stringValue = [array objectAtIndex:0]; 

    // For testing 
    NSLog(@"%@", array); 
} 

Я загрузил файл и получил данные. Я преобразовал данные в NSString. Файл имеет несколько строк, и каждая строка имеет собственное значение. Первая строка - это название документа. Поэтому я создал NSArray, который помещает каждую строку отдельно в массив. Затем я установил первую строку документа на ярлык documentTitle. В целях тестирования я также создал функцию NSLog. Он должен регистрировать массив.

Проблема в том, что когда я запускаю код, он ничего не делает. DocumentTitle.stringValue не изменяется. Но самое странное, что это войти в массив:

2015-09-22 16:57:40.098 DocBased Test[10765:277445] 
(
    "The awesome title!", 
    "This is a document!" 
) 

Я объявленную DocumentTitle в Document.h так:

#import <Cocoa/Cocoa.h> 

    @interface Document : NSDocument 
    { 
     IBOutlet NSTextField *documentTitle; 
    } 

@end 

Если вам необходимо просмотреть проект в Xcode здесь ссылка: The link.

Кто-нибудь знает, как изменить stringValue метки документа (или любой) в поле Документ класс?

+1

Не могли бы вы установить контрольную точку на линии с: 'documentTitle.stringValue' и гарантировать, что' documentTitle' ссылается на объект, а не 'nil'? –

+0

@A O Вы правы. Объект ** documentTitle ** равен нулю. Можешь мне сказать почему? Я никогда не видел этого раньше. – Developer

+1

Тогда идеальное, простое решение. Не могли бы вы разместить строку, в которой вы объявляете '@property documentTitle'? Это «IBOutlet»? –

ответ

1

С учетом вашего проекта @https://www.mediafire.com/?z6drw20suvt0re0,
Мне удалось заставить его работать. Написание нового ответа, потому что мой оригинал уже очень громоздкий и подходит для общего случая; в то время как этот ответ будет очень специфичен с кодом

Только несколько изменений:
1) Потому что ваш владелец Document.xib является Document, вам не нужно перетащить в объекте документа в вашу схему документа. Поэтому я удалил это.
2) Я выбрал сам файл владелец (документ), и настроить подключение к вашей собственности NSTextField
3) Я удалил Ивар

@interface Document : NSDocument 
{ 
    IBOutlet NSTextField *documentTitle; 
} 

так что ваш заголовок теперь выглядит следующим образом:

@interface Document : NSDocument 

@end 

4) Я создал свойство внутри вашего файла реализации (Document.м), а также как NSString свойство (я объясню, что в второй)

@property NSString *titleString; 
@property IBOutlet NSTextField *documentTitle; 

5) Так что, если вы идете вперед и переопределить метод -awakeFromNib (Просто поместите NSLog или что-то в там), вы увидите, что на самом деле -awakeFromNib вызывается ПОСЛЕ -readFromData. Теперь помните, что я сказал - что объект создан, но никаких соединений не производится до тех пор, пока не будет загружено представление и отправлено сообщение -awakeFromNib.

Так что это происходит:

  • Вы нажмите кнопку «Открыть» и выберите файл
  • Ваш Document инстанциируется
  • -readData... вызывается непосредственно во время создания экземпляра, но подключение к NSTextField ISN» t made yet, так что это nil
  • -awakeFromNib называется, и соединения от Document до любого NSView s (включая ваш NSTextField)
  • , но уже слишком поздно.

Таким образом, решение является простым, в методе -readData
, вместо того, чтобы ваши NSTextField «S stringValue, вы должны просто сохранить строку, которую вы прочитать в NSString собственности (То, что я упоминал ранее)

Затем, когда вы вызываете свой -awakeFromNib, вы можете просто получить доступ к этому свойству NSString для значения, которое вы хотите, и затем установить stringValue.

Вот два метода, которые были изменены:

-(void)awakeFromNib 
{ 
    if(self.titleString) 
    { 
     [self.documentTitle setStringValue:self.titleString]; 
    } 
} 

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError { 
    // Insert code here to read your document from the given data of the specified type. If outError != NULL, ensure that you create and set an appropriate error when returning NO. 
    // You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead. 
    // If you override either of these, you should also override -isEntireFileLoaded to return NO if the contents are lazily loaded. 

    NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
    NSArray *array = [string componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; 

    NSLog(@"\r%@", array); 


    self.titleString = [array objectAtIndex:1]; 

    return YES; 
} 

Позвольте мне знать, если вы хотели бы получить больше объяснений в любом месте, но это будет работать для вас :)

+0

Можете ли вы загрузить его на сайт общего доступа к файлам, чтобы я мог его загрузить (если он не тратит впустую ваше время)? И спасибо за то, что вы нашли решение. Я боролся за это уже полгода, поэтому хорошо знать, как это делается. Я ценю это. – Developer

+0

Конечно, здесь вы идете: https://www.dropbox.com/s/0lj1i1ezmv0u9ix/theTestApp%202.zip?dl=0 Но я бы рекомендовал вам прочитать мой ответ и попытаться заставить его работать на себя - это действительно не так уж плохо, если это поможет, если вы поймете причину, почему она не работает. –

+0

Хорошо, я сделаю. Спасибо за ваше время! – Developer

1

К счастью, это общая проблема :)

Определить файл .xib, который содержит ваш NSTextView. Скажем, например, это называется MyViewController.xib.

В интерфейсе Builder откройте панель «Утилиты» (правая панель, кнопка находится в правом верхнем углу). В нижней части панели утилит, нажмите на иконку круга ж/квадрата в нем, и поиск «Объект»

enter image description here

Теперь нажмите и перетащите, что Object в левую сторону (Документ Outline), ниже раздела «Заполнители».

enter image description here

Это создаст новый раздел под названием "Объекты".

Нажмите на новый объект в структуре документа. Теперь обратно в панели Utilities, перейдите на «Удостоверение инспектора»

Измените «Класс», чтобы быть Document

enter image description here

Теперь переходим к «Connections Inspector» и в панели Utilities. Ваш (IB) выходы для Document должны появиться здесь, они будут выглядеть примерно так:
enter image description here

За исключением вместо «nextKeyView» вы увидите documentTitle

Нажмите и перетащите на окружности вправо из розетки и отпустите верхнюю часть вашего NSTextField, чтобы вы были вашим documentTitle.

Теперь давайте поговорим о том, что произойдет.

  • Сначала вы будете создать экземпляр MyViewController с методом, как initWithNibName:...
  • Обратите внимание, что nib, который подпирают MyViewController.xib пока не будет загружен (это называется отложенной загрузки)
  • При попытке доступа view свойство вашего NSViewController, он загрузит перо, связанное с ним
  • перо загружается, объекты внутри него все экземпляры
  • init методы все называют по каждому из этих объектов
  • Выпускные соединения теперь сделаны, в том числе подключение к вашему Document объекта вашему NSTextView
  • -awakeFromNib отправляется на все объекты, экземпляры которых были через бобах

На данный момент ваша недвижимость documentTitle теперь ссылается на действительный объект NSTextField и больше не является nil. Теперь вы можете установить , это stringValue, как вам угодно

Надеюсь, это поможет!

+0

@A O К сожалению, это все равно ноль. Я заметил, что когда вы это сделали, выход в Инспекторе соединений отображается в разделе «Резервные выходы». Моя выставка в разделе «Outlets». Это может быть проблема? И я использую Xcode 7 (бета-версия 5), и я не использую раскадровки OS X (возможно, это полезно). Если это не так, это снова мой Xcode. Я испытывал с ней странные ошибки. Я часто смотрю руководства на YouTube, которые являются правильными, но код просто не работает, когда я пытаюсь. – Developer

+1

Не жалко, мне было слишком ленив, чтобы создать новый проект, но он должен быть в «торговых точках». Вы хотите просто загрузить свой проект в Dropbox или что-то еще, и я могу взглянуть? –

+0

Я загрузил его в MediaFire. Ссылка для скачивания: [https://www.mediafire.com/?z6drw20suvt0re0](https://www.mediafire.com/?z6drw20suvt0re0). Конечно, это безопасная загрузка. MediaFire не позволял мне загружать папки, поэтому это файл .zipx. Вы можете открыть его с помощью приложения iZip (бесплатно от AppStore). Я также поставил тестовый файл для загрузки приложения. И спасибо за ваш интерес к этому вопросу. Я очень благодарен. – Developer

Смежные вопросы