четверг, 30 сентября 2010 г.

Прокрутка и масштабирование в UIScrollView

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

Вам может потребоваться возможность сдвигать контент в сторону от его изначального положения.

Но если размер вложенного в UIScrollView-вид контентного вида (например UIView или его наследника) равен размеру UIScrollView-вида (то есть размеру контейнера для вашего контента) ИЛИ если вы забыли установить у UIScrollView-вида свойство contentSize таким, чтобы размеры контента были явно больше размеров самого UIScrollView-вида, то прокрутка будет невозможна (или возможно, но только после растягивания контента, чтобы он стал больше размера родительского окна, то есть UIScrollView-вида).

Есть 2 способа сделать возможной прокрутку:
1) сделать изначально большим размер контентного окна и не забыть установить таким же размер через свойство contentSize вашего UIScrollView-вида.
2) установить свойство contentInset, которое устанавливает дополнительное пространство слева, справа, сверху и снизу от контентного окна, чтобы дать возможность его прокручивать (если размеры контентного окна совпадают с размерами родительского окна).

Так вот, я проверил лично: 2-й способ лучше именно для тех случаев, если вам не нужно размещать большой контент, а именно такой, который размером совпадает с UIScrollView-видом (даже если вы и будете его потом растягивать пальцами). Этот способ заметно экономит потребляемую девайсом память, а значит уменьшает шансы на недопустимое падение программы без всякого предупреждения и спасения данных.

среда, 15 сентября 2010 г.

Переполнение памяти из-за больших размеров окон (UIView)

Разрабатываемое iPhone-приложение может начать неожиданно падать и при этом отладчик никак не в состоянии помочь.

После нескольких дней поиска (когда программа перестала падать после закомментирования содержимого функции drawRect класса моего окна, наследующего от UIView) удалось случайно выяснить, что слишком большой размер окна (который можно задать либо в Interface Builder либо через self.bounds.size) требует слишком много памяти (в моём случае - это цена за возможность безтормозной прокрутки такого большого окна, если оно отображает контент для UIScrollView). Размер окна составлял примерно 4000 на 2500 пикселей.

Стоило лишь уменьшить размер окна в половину, как падение программы прекратилось.

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

вторник, 14 сентября 2010 г.

Как вывести в отладочную консоль используемую память в iPhone-приложении

Материал взят из
http://stackoverflow.com/questions/2786539/iphone-memory-usuage

#import mach/mach.h

void report_memory(void) {
struct task_basic_info info;
mach_msg_type_number_t size
= sizeof(info);
kern_return_t kerr
= task_info(mach_task_self(),
TASK_BASIC_INFO
,
(task_info_t)&info,
&size);
if( kerr == KERN_SUCCESS ) {
NSLog(@"Memory used: %u", info.resident_size); //in bytes
} else {
NSLog(@"Error: %s", mach_error_string(kerr));
}
}

среда, 8 сентября 2010 г.

Проблемы с UIScrollView и Landscape ориентацией интерфейса

Обнаружил, что при использовании Interface Builder'а (если в нём создавать окно, содержащее UIScrollView окошко) возникают существенные проблемы при попытке обеспечить поддержку не только Portrait но и Lanscape ориентации интерфейса.

Моя задача: автоматически перестраивать размеры контент-вида (именно того вида, который передвигается внутри UIScrollView) так, чтобы его длина и ширина были больше длины и ширины UIScrollView окошка в целое число раз (константу) при любом положении девайса.

Сейчас (истратив десятки часов на е..лю с горячо любимым Xcode) я прихожу к выводу, что бесполезно пытаться программно перестраивать размеры контент-вида (того самого, который можно передвигать пальцем используя UIScrollView). Приложение всё равно игнорирует (во всяком случае при визуальном тестировании на девайсе) весь ваш код, и продолжает упёрто принимать во внимание только тот размер, который вы задавали контент-виду через Interface Builder.

Оказывается, требуется в настройках (см. Inspector в Interface Builder) главного окна (в котором будет расположено окошко UIScrollView) и в настройках самого UIScrollView окошка поставить галочку Autoresize Subviews.

Кроме того, важно выставить правильные настройки (в виде красных отрезков и стрелочек) в разделе Autosizing (см. Inspector в Interface Builder). Мне удалась моя задача, как только я выставил только красные стрелочки и убрал красные отрезки в настройках контент-вида. То есть программное изменение размеров и оффсета контента я в коде тоже оставил и это вероятно работает теперь в совокупности (не стал это выяснять, чтобы не злоупотреблять рабочим временем - главное теперь работает как надо).

Обидно, что для выяснения подобных тонкостей уходят многие часы. Хотя это - цена за бесценный опыт.

ЧЕРЕЗ НЕСКОЛЬКО ЧАСОВ: Теперь после многочасовой возни с отладчиком и отладочной консолью удалось выяснить основную причину всех моих бед.

При повороте девайса можно перехватывать это событие (поворот девайса) как вариант в функции shouldAutorotateToInterfaceOrientation (подробности через Гугл). Так вот, при перехвате этого события размеры Autoresize-окон ещё не поменялись! Если вы будете вызывать при перехвате этого события какие-то функции (меняющие размеры ваших сущностей, в которых вы что-то рисуете), то нельзя ориентироваться на текущие bounds (размеры) ваших окон, которые ещё не успели красиво повернуться, подстроившись под новое положение девайса!

Есть и другая проблема с Autoresize-окнами. Если при перехвате события (поворота девайса) вы захотите поменять размеры этих окон программно, то после этого Autoresize-окна автоматически перестроятся под новое положение девайса (поменяв свои размеры возможно не так, как вам бы хотелось).

четверг, 2 сентября 2010 г.

CodeFest — конференция разработчиков в Новосибирске 23 сентября

http://codefest.ru/

CodeFest —
конференция разработчиков, посвященная актуальным вопросам разработки, управления проектами и тестирования. Достойные гуру интернет-технологий съезжаются со всей России, чтобы вдохнуть глоток свежих знаний, встретить старых знакомых и завести новые связи.

Постоянные читатели