Показаны сообщения с ярлыком iPhone OS. Показать все сообщения
Показаны сообщения с ярлыком iPhone OS. Показать все сообщения

16 декабря 2010 г.

Градиент на UINavigationBar

Так уж захотелось заказчику, что б на фон компоненты UINavigationBar плавно перетекал из одного цвета в другой. Решение было найдено довольно быстро.

Будем модифицировать метод drawRect: компоненты UINavigationBar

  1. - (void) drawRect:(CGRect) rect
  2. {
  3. // подготовка контекста для рисования
  4. CGContextRef context = UIGraphicsGetCurrentContext();
  5. CGFloat locations[2] = { 0.0, 1.0 };
  6. CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
  7. // создаем и рисуем градиент
  8. CGFloat components[8] = COLOR_COMPONENTS;
  9. CGGradientRef gradient = CGGradientCreateWithColorComponents(myColorspace, components, locations, 2);
  10. CGContextDrawLinearGradient(context, gradient, CGPointMake(0, 0), CGPointMake(0,self.frame.size.height), 0);
  11. CGGradientRelease(gradient);
  12. CGColorSpaceRelease(myColorspace);
  13. // верхнюю линию компоненты делаем белой
  14. CGContextSetRGBStrokeColor(context, 1, 1, 1, 1.0);
  15. CGContextMoveToPoint(context, 0, 0);
  16. CGContextAddLineToPoint(context, self.frame.size.width, 0);
  17. CGContextStrokePath(context);
  18. // нижнюю линию закрашиваем черным цветом
  19. CGContextSetRGBStrokeColor(context, 0, 0, 0, 1.0);
  20. CGContextMoveToPoint(context, 0, self.frame.size.height);
  21. CGContextAddLineToPoint(context, self.frame.size.width, self.frame.size.height);
  22. CGContextStrokePath(context);
  23. }


Пример можно скачать с github

5 октября 2010 г.

Добавление изображений в iPhone Simulator

Если необходимо добавить в iPhone Simulator несколько изображений, то этот способ вам подойдет.
Открываем iPhone Simulator и перетаскиваем в него изображение из Finder. Это изображение откроется в приложении Mobile Safari на iPhone Simulator. Теперь просто кликаем на нем и удерживаем кнопку мыши нажатой до появления вплывающего меню (имитируем долгий тап на изображении).


Теперь нажимаем на "Save Image" и изображение попадает в Фотоальбом.

Если нужно добавить большое кол-во изображений или создавать в симуляторе фотоальбомы, для iPhone Simulator версий 3.х есть довольно простое решение: в папку ~/Library/Application Support/iPhone Simulator/4.1/Media/DCIM/100APPLE поместить два изображения.
первое IMG_хххх.JPG - изображение которое мы помещаем в Фотоальбом симулятора в формате jpeg
второе - IMG_хххх.THM - привью первого изображения в формате jpeg размером 96x96
Скрипт на Python который добавляет изображения в Фотоальбом iPhone Simulator-а.

Для iPhone Simulator версий 4.х нужно дополнительно править sqlite базы.

Так-же можно написать iPhone приложение которое будет в себе как ресурс содержать изображения и в цикле будет добавлять в фотоальбом изображения.

2 октября 2010 г.

Добавление изображений в Фотоальбом

Этот пост посвящен единственной функции из фраемворка UIKit, а именно UIImageWriteToSavedPhotosAlbum. В параметры функции передается изображение класса UIImage, а так-же функция-селектор которая вызовется после добавления изображения в Фотоальбом, либо при возникновении ощибки добавления.

Скачать пример.

25 августа 2010 г.

Запись аудио с микрофона iPhone

Во времена прошивок 2.х для меня стало открытием, что подключив гарнитуру к iPod Touch можно использовать микрофон для записи аудио. А вот в 3-й прошивке появилось приложение "Диктофон", так что возможность подключения микрофона стала очевидной.

Есть несколько способов записи звука с вашего приложения. Я расскажу о наборе функций из фраемворка AudioToolbox.

Запись осушествляется через специально подготовленные буфера, по мере их заполнения они отсылаются функции-слушателю, а там уже программист решает: записать буфер в файл, отправить в сеть или обработать как-то по своему. Но для начала нужно все подготовить.

Для задания формата входного буфера и параметров аудио используется структура AudioStreamBasicDescription. Эта структура передается в функцию AudioQueueNewInput, эта функция создает новый объект для записи.

  1. AudioStreamBasicDescription mDataFormat;
  2. mDataFormat.mFormatID = kAudioFormatLinearPCM;
  3. mDataFormat.mSampleRate = 44100;
  4. mDataFormat.mChannelsPerFrame = 1;
  5. mDataFormat.mBitsPerChannel = 16;
  6. mDataFormat.mBytesPerPacket =
  7. mDataFormat.mBytesPerFrame = mDataFormat.mChannelsPerFrame * sizeof(short int);
  8. mDataFormat.mFramesPerPacket = 1;
  9. mDataFormat.mFormatFlags = kLinearPCMFormatFlagIsBigEndian
  10. | kLinearPCMFormatFlagIsSignedInteger
  11. | kLinearPCMFormatFlagIsPacked;
  12. AudioQueueRef queue;
  13. AudioQueueNewInput(&mDataFormat, AQInputCallback,
  14. NULL, NULL, kCFRunLoopCommonModes, 0, &queue);


Вторым параметром задается функция-слушатель, которая вызывается по мере заполнения аудиобуферов. В ней и происходит вся работа по обработке аудио, будь то запись в файл или отсылка в сеть.

Теперь необходимо подготовить аудиобуферы в которые будет помещаться считанный аудиопоток. Функция AudioQueueAllocateBuffer выделяет память под буфер, а AudioQueueEnqueueBuffer добавляет к нашему объекту для записи полученный функцией AudioQueueNewInput.

  1. unsigned long frameSize = mDataFormat.mSampleRate * mDataFormat.mBytesPerFrame;
  2. AudioQueueBufferRef aBuffers[AUDIO_BUFFERS];
  3. for (int i=0; i<AUDIO_BUFFERS; i++)
  4. {
  5. AudioQueueAllocateBuffer(queue, frameSize, &aBuffers[i]);
  6. AudioQueueEnqueueBuffer(queue, aBuffers[i], 0, NULL);
  7. }


Подготовка закончена. Запускаем запись аудио функцией AudioQueueStart.

  1. AudioQueueStart(queue, NULL);


Остановить запись можно функцией AudioQueueStop:

  1. AudioQueueStop(queue, true);


И освобождение памяти от объекта queue функцией AudioQueueDispose

  1. AudioQueueDispose(queue, true);


Пример от Apple SpeakHere мне показался большим и сложным для понимания, мой более компактный.

20 августа 2010 г.

Веб-приложение для iPhone (ориентация и определение устройства)

Рассмотрим несколько простых трюков в на java-script которые помогут определить, что этот java-script запущен на iУстройстве а так-же подписаться на событие изменения положения устройства.

Строка navigator.appVersion дает много полезной информации о браузере в котором выполняется java-script. Можно например так узнать, выполняемся ли мы на iPhone:

  1. if (navigator.appVersion.indexOf('iPhone OS ') >= 0)
  2. {
  3. // this iPhone
  4. }

так же, браузер вызывает каждый раз при изменении ориентации устройства метод window.onorientationchange, ее можно легко переопределись:

  1. window.onorientationchange = function ()
  2. {
  3. switch ( window.orientation )
  4. {
  5. case 0:
  6. case 180:
  7. // portrait mode
  8. break;
  9. case -90:
  10. case 90:
  11. // landscape mode
  12. break;
  13. }
  14. };

еще переменная window.navigator.standalone указывает на то, запущено наше приложение в браузере или установлено как отдельное приложение.

как-то сухо все получилось, я учусь.
Пример доступен по классической ссылке, либо по qr-коду:

18 августа 2010 г.

Размер клавиатуры в iOS

Иногда необходимо узнать размер виртуальной клавиатуры из приложения. Например чтоб изменить положение/размер ваших визуальных компонентов на view. До появления iPad/iPhone 4 можно было смело использовать константы. С выходом устройств с различным разрешением экрана константы использовать нельзя.

Первое, что нам понадобится, зарегистрировать слушателя на появление клавиатуры на экране (делается это например в методе viewDidAppear: вашего UIViewController):

  1. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShown:) name:UIKeyboardWillShowNotification object:nil];

в конце не забываем отписаться от получения сообщений повеления клавиатуры

  1. [[NSNotificationCenter defaultCenter] removeObserver:self];

а вот и сама функция-слушатель:

  1. - (void) keyboardWillShown:(NSNotification*) aNotification
  2. {
  3.   NSDictionary* info = [aNotification userInfo];
  4.  
  5.   #ifdef __IPHONE_4_0
  6.   NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
  7.   if (!aValue)
  8.   {
  9.     aValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
  10.   }
  11.   #else
  12.   NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
  13.   #endif
  14.  
  15.   CGSize keyboardSize = [aValue CGRectValue].size;
  16.   NSLog(@"%.1fx%.1f", keyboardSize.width, keyboardSize.height);
  17. }

тут мы просто печатаем в лог размер виртуальной клавиатуры.

Пример, таблица в каждом элементе которой есть UITextField при выборе которого таблица центруется на этом элементе.

16 августа 2010 г.

Установка приложения на устройство с прошивкой 3.х из Xcode 3.2.4

Аpple из новых версий Xcode убрали iPhone Simulator версий 2.х и 3.х. Так же базовой версией SDK можно поставить только версии 4.х. Не обязательно держать установленным две версии Xcode для поддержки из вашего приложения версий 3.х и 4.х. Из новой версии Xcode можно устанавливать приложения на устройства с прошивкой 3.0, для этого нужно в свойствах проекта выставить свойство "iOS Deployment Target" на нужную версию SDK вашего устройства.

По комментариям статьи.

PS: перед использованием функций которых нет в более ранних версиях SDK следует проверять их наличие

  1. if ([obj respondsToSelector:@selector(someSelector:)])
  2. {
  3.   [obj performSelector:self withObject:nil];
  4. }

7 августа 2010 г.

Информация о сети

В iOS 4.0 Apple дала возможность разработчикам получить информацию о сети в которой находится телефон, а так-же о текущих звонках. Итак, фраемворк CoreTelephony. Он представлен всего несколькими классами, но из них можно вынести интересную информацию. Класс CTCarrier содержит информацию о сети, CTCall - о текущем звонке. Подписаться на получение изменений информации о звонках и изменении сети можно зарегистрировав слушателей subscriberCellularProviderDidUpdateNotifier и callEventHandler в классах CTTelephonyNetworkInfo и CTCallCenter.

Простой пример

4 августа 2010 г.

Local Notifications в iOS 4.0

Начиная с iOS SDK 4.0 появилась возможность отсылать локальные сообщения. Локальные сообщения - это сообщения пользователю от вашей программы в определенное время, не зависимо от того, запущено ли ваше приложение. Очень похоже на Push Notification но действует только в пределах одного устройства (без участия севера). Как и Push Notification Local Notification может быть доставлен пользователю как: звуковое сообщение, цифра на иконке приложения и как алерт. Не думайте, что при посылке Local Notification ваше приложение запустится, это произойдет только в том случае, если ваше Local Notification имеет тип алерт и пользователь на этом всплывающем окне нажал кнопку "View". Так что никакой важной информации не стоит доставлять через Local Notification, хотя эти сообщения и надежнее чем Push Notification так как не зависят от состояния сети.

Регистрация в системе Local Notification осуществляет метод scheduleLocalNotification: класса UIApplication. Параметром этого метода служит объект класса UILocalNotification. Код который осуществляет отсылку сообщения:

  1. UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];
  2.  if (alarm)
  3.  {
  4.   alarm.fireDate = [[NSDate date] dateByAddingTimeInterval:30.0];
  5.   alarm.timeZone = [NSTimeZone defaultTimeZone];
  6.   alarm.repeatInterval = 0;
  7.   alarm.alertBody = @"local notification";
  8.   UIApplication *app = [UIApplication sharedApplication];
  9.   [app scheduleLocalNotification:alarm];
  10.  }

Этот код создает объект alarm типа alert c текстом "local notification" и регистрирует его в системе как событие, которое произойдет через 30 сек.

Посмотреть зарегистрированные в системе от вашего приложении нотификации позволяет метод scheduledLocalNotifications. Отменить все нотификации можно методом cancelAllLocalNotifications.

Что э происходит если событие нотификации происходит при запущенном приложении? Системных событий тогда никаких не происходит (не звуков не проигрывается, не показывается всплывающее окно), но делегату вашего приложения приходит событие application:didReceiveLocalNotification: в котором можно обработать сообщение.

Пример работы.

27 июля 2010 г.

MapKit в iOS

В моем старом приложении требовалась поддержка прошивки iPhone OS 2.х. Поэтому я не мог использовать все прелести фраемворка MapKit, который появился в 3.0 прошивке. В те далекие времена (около года назад) я отображал карту через UIWebView. Так как сейчас количество устройств с установленной на них прошивками 2.х ничтожно мало, было принято решение переходить на встроеные компоненты отображения карты.

Отобразить в вашем приложении карту можно используя класс MKMapView из фраемворка MapKit. Класс представляется множеством очевидных методов: mapType, zoomEnabled, region, showUserLocation, которые настраивают внешний вид карты. Но это все просто, мне было интересно добавлять на карту свои объекты. С этим мы и будем разбираться в данной статье.

Для добавления на карту элемента привязанного к одной геокоординате используется метод addAnnotation:. В качестве аргумента он принимает объект который наследует протокол MKAnnotation. Протокол реализует методы задания координаты нашей аннотации (coordinate), задание заголовка аннотации (title) и ее текста (subtitle). Вот самый простой пример объекта аннотации:

marker.h
  1. @interface marker : NSObject <MKAnnotation>
  2. {
  3. }
  4. @end


marker.m
  1. #import "marker.h"
  2.  
  3. @implementation marker
  4. #pragma mark MKAnnotation
  5. - (CLLocationCoordinate2D) coordinate
  6. {
  7.   return CLLocationCoordinate2DMake(46.462585, 30.750186);
  8. }
  9.  
  10. - (NSString *) title
  11. {
  12.   return @"This annotation";
  13. }

создадим экземпляр этого объекта и добавим его на карту:

  1. marker *m = [[marker alloc] init];
  2. [mapView addAnnotation:m];
  3. [m release];

довольно просто, правда ведь? Если мы хотим кустимизировать нашу аннотацию, например изменить иконку иголочки, то нам необходимо использовать метод mapView:viewForAnnotation: делегата нашей карты, пример приведен в конце статьи.

Пусть теперь мы хотим нарисовать на карте объект привязанный к нескольким геокоординатам (например маршрут из точки А в точку В). Тут нужно добавлять не аннотацию, а оверлей addOverlay:. Добавим в него MKPolyline:

  1. CLLocationCoordinate2D mapCoords[6];
  2. mapCoords[ 0] = CLLocationCoordinate2DMake(46.476472, 30.704776);
  3. mapCoords[ 1] = CLLocationCoordinate2DMake(46.469664, 30.732229);
  4. mapCoords[ 2] = CLLocationCoordinate2DMake(46.462585, 30.750186);
  5. mapCoords[ 3] = CLLocationCoordinate2DMake(46.447197, 30.743040);
  6. mapCoords[ 4] = CLLocationCoordinate2DMake(46.415384, 30.723226);
  7. mapCoords[ 5] = CLLocationCoordinate2DMake(46.409143, 30.729909);
  8. MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:mapCoords count:6];
  9. [mapView addOverlay:polyLine];
  10. [mapView setDelegate:self];


и в делегате нашей карты зададим свойства этой линии

  1. - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
  2. {
  3.  MKPolylineView *polylineView = [[[MKPolylineView alloc] initWithOverlay:overlay] autorelease];
  4.  polylineView.strokeColor = [UIColor blueColor];
  5.  polylineView.lineWidth = 3.0;
  6.  return polylineView;
  7. }


Пример проекта.

Так же смотрите:
- Конвертирование "человеческого" адреса в широту и долготу

21 июля 2010 г.

Работа с музыкальной библиотекой iPod в iOS

Возникла у меня задача, проверить программно, присутствует ли конкретная песня в библиотеке пользователя на iPhone/iPod Touch, и если есть, то проиграть ее. Итак, будем программировать работу с библиотекой iPod.

Для взаимодействия с музыкальной библиотекой в iOS существует класс MPMusicPlayerController из фраемворка MediaPlayer. Функций вроде и не много, но они покрывают практически все возможности приложения iPod.app. При создании экземпляра класса можно выбрать, каким плейером будем пользоваться, созданным отдельно для приложения(метод applicationMusicPlayer), или глобальным плейером iPod(метод iPodMusicPlayer). Первый выгрузится при закрытии приложения, второй может продолжать работать после закрытия приложения. Будем работать с глобальным плейером iPod.

Вызвав метод play мы уже можем услышать музыку доносящуюся из динамиков устройства (iPhone Sumulator не подключается к библиотеке iTunes). Если нужно знать, когда закончилась/сменилась песня нужно зарегистрировать слушателя:

  1. MPMusicPlayerController *ipod = [MPMusicPlayerController iPodMusicPlayer];
  2. [[NSNotificationCenter defaultCenter] addObserver:self
  3.   selector:@selector(playbackItemChanged:)
  4.   name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification
  5.   object:ipod];
  6. [ipod beginGeneratingPlaybackNotifications];

тут мы регистрируем функцию playbackItemChanged: текущего класса как слушателя события изменения песни в iPod.

Хорошо, сейчас мы можем прослушивать песни из пленэра, но не можем выбирать, что слушать. Звуковой файл представляется в библиотеке классом MPMediaItem. Но просто так его создать нельзя, его нужно получать фильтруя из музыкальной библиотеки данные. Для фильтрации используется класс MPMediaQuery. Тут можно отфильтровать библиотеку по разным множеству категориям (таким как жанр, аудиокниги, подкасты, плечисты), а также можно добавлять свои фильтры.

  1. [ipod setQueueWithQuery:[MPMediaQuery songsQuery]];
  2. [ipod play];

И по традиции пример приложения.

16 июля 2010 г.

Проигрывание музыки с помощью iPhone SDK

Присутствие звуковых эффектов и музыки сильно улучшает ваше приложение. Сегодня я расскажу как с помощью iPhone SDK управлять проигрыванием звукового файла. Речь пойдет о проигрывали больших звуковых файлов с возможностью приостановки и изменении позиции проигрывания.
Я буду использовать класс AVAudioPlayer из фраемворка AVFoundation. Напишем приложение которое будет циклически проигрывать файл с возможностью перемотки. Я не использую Interface Builder поэтому не буду приводить скриншоты расположения элементов на экране. Итак, в в нашем вью присутствует кнопка старта/остановки проигрывания (playStopBtn), слайдер показывающий позицию в проигрываемом файле (tmSlider) и свичер разрешающий играть музыку при залоченом экране.
Первое, что необходимо сделать, так это создать наш плейер и настроить его. Например в методе init или loadView прописываем:

  1. NSURL *file = [[NSURL alloc] initFileURLWithPath:
  2.     [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"a_hot.caf"]];
  3. NSError *err = nil;
  4. player = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:&err];
  5. [file release];
  6. player.numberOfLoops = -1;
  7. player.delegate = self;
  8. [player prepareToPlay];

в результате плейер у нас создан, и в него загружен наш звуковой файл.
Описываем событие нажатия на кнопку playStopBtn:

  1. if (player.playing)
  2. {
  3.  [player stop];
  4.  [playStopBtn setTitle:NSLocalizedString(@"Play", @"") forState:UIControlStateNormal];
  5.  [tmUpdaterTimer invalidate];
  6.  [tmUpdaterTimer release];
  7.  tmUpdaterTimer = nil;
  8. }
  9. else
  10. {
  11.  [player play];
  12.  [playStopBtn setTitle:NSLocalizedString(@"Stop", @"") forState:UIControlStateNormal];
  13.  tmUpdaterTimer = [[NSTimer scheduledTimerWithTimeInterval:0.2
  14.  target:self selector:@selector(timerAction:)
  15.  userInfo:nil repeats:YES] retain];
  16. }

тут все просто, если сейчас играет музыка - останавливаем ее проигрывание, исли плейер на паузе - начинаем проигрывание. Так-же тут создается/уничтожается таймер, который изменяет позицию слайдера при проигрывали:

  1. - (void) timerAction:(NSTimer *) sender
  2. {
  3.   [tmSlider setValue:player.currentTime animated:YES];
  4. } 

У слайдера показывающего позицию в проигрываемом файле тоже есть два слушателя на изменение позиции и окончание изменения позиции:

  1. - (void) changeTime:(UISlider *) sender
  2. {
  3.   if (!moving)
  4.   {
  5.     isPlaying = player.playing;
  6.     if (player.playing)
  7.     {
  8.       [player stop];
  9.     }
  10.     moving = YES;
  11.   }
  12.   player.currentTime = sender.value;
  13. }
  14.  
  15. - (void) endChangeTime:(UISlider *) sender
  16. {
  17.   moving = NO;
  18.   if (isPlaying)
  19.   {
  20.     [player play];
  21.   }
  22. }

при начале перетаскивания ползунка проверяем, играет ли музыка, если да, то приостанавливаем проигрывание в конце востанавливаем состояние.

Все проигрывается, но при блокировке экрана музыка приостанавливается. Следующий код разрешает проигрывание музыки при выключенном экране устройства:

  1. AudioSessionInitialize(NULL, kCFRunLoopDefaultMode, NULL, self);
  2. UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
  3. AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
  4. AudioSessionSetActive(true);

Мой пример использующий все выше написанное можно скачать

13 июля 2010 г.

Отсылка почты из вашего приложения встроенным клиентом Mail в iOS

Вот решил написать несколько статей по программированию под iPhone/iPod Touch/iPad.
Для начала выбрал простенькую тему описывающуюся одним классом в SDK и несколькими методами. Итак, отсылка почты из вашего приложения встроенным клиентом Mail.
Работу отсылки почты осуществляет класс MFMailComposeViewController наследник от стандартного UIViewController-а. Первое, что необходимо сделать, это подключить к вашему проекту фраемворк MessageUI.

Потом подключить описание этого фраемворка.

Теперь можно кодить.

  1. // Перед тем как вызывать диалог отсылки почты необходимо проверить настроен ли у пользователя вообще почтовый клиент.
  2. if (![MFMailComposeViewController canSendMail])
  3. {
  4.   // Клиент не настроен, показываем всплывающее окно.
  5.  UIAlertView *tmp = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Warning", @"") message:NSLocalizedString(@"Your e-mail application not configured", @"") delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles:nil];
  6.  [tmp show];
  7.  [tmp release];
  8.  return ;
  9. }
  10.  // создаем экземпляр обекта MFMailComposeViewController
  11. MFMailComposeViewController *mcvc = [[MFMailComposeViewController alloc] init];
  12.  // указываем обект делегата (слушателя)
  13. mcvc.mailComposeDelegate = self;
  14.  // заполняем поле "Кому"
  15. [mcvc setToRecipients:[NSArray arrayWithObject:@"test@example.com"]];
  16.  // заполняем поле "Тема"
  17. [mcvc setSubject:NSLocalizedString(@"Testing mail", @"")];
  18.  // пишем тело письма
  19. [mcvc setMessageBody:NSLocalizedString(@"This is body of mail", @"") isHTML:NO];
  20.  // прикрепляем к письму данные как текст и указываем имя файла приложения к письму
  21. [mcvc addAttachmentData:[@"Text on attach" dataUsingEncoding: NSUTF8StringEncoding] mimeType:@"text/plain" fileName:@"test.txt"];
  22.  // показываем заполненный контрол
  23. [self presentModalViewController:mcvc animated:YES];

Нужно помнить, что контрол сам не убирается после нажатия кнопки "Отправить", поэтому в методе слушателе (mailComposeController:didFinishWithResult:error:) закроем наш контрол:

  1. - (void) mailComposeController:(MFMailComposeViewController*) controller didFinishWithResult:(MFMailComposeResult) result error:(NSError*) error
  2. {
  3.  [controller dismissModalViewControllerAnimated:YES];
  4. }

Проект для xCode можно скачать.

7 октября 2009 г.

Установка iphone-gcc на iPhone/iPod с прошивкой 3.х

Из Cydia пакет gcc на iPhone не устанавливается из-за битой libgcc. Для установки нам понадобится командная строка на устройстве:

  1. $ wget http://apt.saurik.com/debs/libgcc_4.2-20080410-1-6_iphoneos-arm.deb
  2. $ sudo dpkg -i libgcc_4.2-20080410-1-6_iphoneos-arm.deb
  3. $ sudo apt-get install iphone-gcc

(c) iphonesdkdev.blogspot.com