#iphone #objective-c #three20
#iPhone #objective-c #three20
Вопрос:
Я новичок в разработке iOS. Для моего маленького мессенджера мне нужен инструмент выбора контактов и текстовое поле. Итак, TTMessageController проекта Three20 кажется очень интересным.
Однако я не совсем уверен, как это реализовать. На данный момент у меня есть три контроллера, по одному для каждого представления. Я хочу иметь средство выбора контактов и текстовую область в третьем представлении.
Я успешно настроил three20. Но как мне это использовать? Могу ли я использовать его через interface builder или просто с помощью кода? Каким был бы подход в моем случае?
Прежде чем я начну работать над этим, я хочу быть уверен, что это правильное решение. Правда ли, что three20 позволяет мне решать, как обрабатывать входные данные, поступающие из текстовых полей? Я хочу отправлять sms с помощью моего собственного шлюза.
Ответ №1:
Посмотрите на исходный код для примера приложения TTCatalog, которое поставляется с исходным кодом three20. В нем приведен пример вызова TTMessageController и обработки полей. По сути, вы реализуете TTMessageControllerDelegate в своем классе, и TTMessageController отправит вам поля из сообщения для обработки после нажатия кнопки отправки. Я использую этот класс в качестве интерфейса для отправки SMS-сообщений через сторонний шлюз в моем приложении. Я объединил его с пузырьковым представлением сообщений, чтобы имитировать родное приложение SMS, и оно работает как чемпион.
РЕДАКТИРОВАТЬ: Если на данный момент у вас есть только скелет контроллера представления, возможно, вам лучше клонировать MessageTestController в ваше приложение и адаптировать его, а не пытаться переопределить его части в вашем контроллере. Единственное, чего не делает примерное приложение, это подключает MessageController к вашей адресной книге. Для этого вам нужно будет создать AddressbookModel и AddressBookModelDataSource следующим образом:
AddressbookDataSource.h
#import <Three20/Three20.h>
@class AddressBookModel;
@interface AddressBookDataSource : TTSectionedDataSource {
AddressBookModel* _addressBook;
}
@property(nonatomic,readonly) AddressBookModel* addressBook;
@end
AddressbookDataSource.m
#import <AddressBookUI/AddressBookUI.h>
#import "AddressBookDataSource.h"
#import "AddressBookModel.h"
@implementation AddressBookDataSource
@synthesize addressBook = _addressBook;
///////////////////////////////////////////////////////////////////////////////////////////////////
// NSObject
- (id)init {
if (self = [super init]) {
_addressBook = [AddressBookModel new];
self.model = _addressBook;
}
return self;
}
- (void)dealloc {
RELEASE_SAFELY(_addressBook);
RELEASE_SAFELY(self.items);
[super dealloc];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// TTTableViewDataSource
- (void)tableViewDidLoadModel:(UITableView*)tableView {
RELEASE_SAFELY(self.items);
self.items = [NSMutableArray new];
int countPeople = [((AddressBookModel *)self.model).searchResults count];
for (int i = 0; i < countPeople; i ) {
ABRecordRef person = [((AddressBookModel*)self.model).searchResults objectAtIndex:i];
ABMultiValueRef phoneNumberMultiValueRef = ABRecordCopyValue(person, kABPersonPhoneProperty);
NSArray* phoneNumbers = (NSArray*)ABMultiValueCopyArrayOfAllValues(phoneNumberMultiValueRef);
RELEASE_CF_SAFELY(phoneNumberMultiValueRef);
if ([phoneNumbers count]) {
NSString *personName = (NSString *)ABRecordCopyCompositeName(person);
for (NSString *phoneNumber in phoneNumbers) {
TTTableItem* item = [TTTableSubtitleItem itemWithText:personName subtitle:phoneNumber];
[_items addObject:item];
}
RELEASE_SAFELY(personName);
}
RELEASE_SAFELY(phoneNumbers);
}
}
- (void)search:(NSString*)text {
[_addressBook search:text];
}
- (NSString*)titleForLoading:(BOOL)reloading {
return @"Searching...";
}
- (NSString*)titleForNoData {
return @"No names found";
}
@end
AddressBookModel.h
#import <Three20/Three20.h>
@interface AddressBookModel : NSObject <TTModel> {
NSMutableArray* _delegates;
NSArray* _searchResults;
}
@property(nonatomic,retain) NSArray* searchResults;
- (void)search:(NSString*)text;
@end
AddressBookModel.m
#import "AddressBookModel.h"
#import <AddressBookUI/AddressBookUI.h>
@implementation AddressBookModel
@synthesize searchResults = _searchResults;
- (id)init {
if (self = [super init]) {
_delegates = nil;
_searchResults = nil;
}
return self;
}
- (void)dealloc {
RELEASE_SAFELY(_delegates);
RELEASE_SAFELY(_searchResults);
[super dealloc];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// TTModel
- (NSMutableArray*)delegates {
if (!_delegates) {
_delegates = TTCreateNonRetainingArray();
}
return _delegates;
}
- (BOOL)isLoadingMore {
return NO;
}
- (BOOL)isOutdated {
return NO;
}
- (BOOL)isLoaded {
return YES;
}
- (BOOL)isLoading {
return NO;
}
- (BOOL)isEmpty {
return !_searchResults.count;
}
- (void)load:(TTURLRequestCachePolicy)cachePolicy more:(BOOL)more {
}
- (void)invalidate:(BOOL)erase {
}
- (void)cancel {
[_delegates perform:@selector(modelDidCancelLoad:) withObject:self];
}
- (void)search:(NSString*)text {
[self cancel];
if (text.length) {
[_delegates perform:@selector(modelDidStartLoad:) withObject:self];
ABAddressBookRef addressBook = ABAddressBookCreate();
CFStringRef searchText = CFStringCreateWithCString(NULL, [text cStringUsingEncoding:NSUTF8StringEncoding], kCFStringEncodingUTF8);
self.searchResults = (NSArray*) ABAddressBookCopyPeopleWithName(addressBook, searchText);
RELEASE_CF_SAFELY(searchText);
[_delegates perform:@selector(modelDidFinishLoad:) withObject:self];
RELEASE_CF_SAFELY(addressBook);
} else {
self.searchResults = nil;
}
[_delegates perform:@selector(modelDidChange:) withObject:self];
}
@end
Работа с адресной книгой была действительно самой сложной частью всего упражнения. Остальное действительно просто.
Комментарии:
1. Я нашел MessageTestController, но я не уверен, какой код мне нужен для моего приложения. У меня есть SecondViewController (UIViewController), который пуст, и я хочу добавить функцию составления sms в это представление. Не могли бы вы предоставить немного больше помощи по этому вопросу, пожалуйста
2. Спасибо, я собираюсь попробовать это. Однако у меня есть MainViewController с панелью навигации и кнопкой «составить». Я хочу, чтобы композитор появлялся при нажатии. TTMessageViewController для меня странный, потому что пользовательский интерфейс и фоновая логика немного перепутаны…
3. Да, это то, что я делаю в своем приложении. Просто создайте подобный метод для вашей кнопки создания.
- (void)add { TTMessageController* messageComposer = [[TTMessageController alloc] initWithRecipients:nil messageText:@""]; messageComposer.delegate = self; [self presentModalViewController:messageComposer.navigationController animated:YES]; RELEASE_SAFELY(messageComposer); }
4. Я получаю предупреждение при выполнении: с помощью object, в нем xcode4 говорится, что этот метод не найден. Вы тоже получаете это предупреждение? Xcode4 говорит, что я должен использовать performSelector: withObject, но мое приложение вылетает… есть идеи?