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

Objective-C

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.83
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 581
#1

Программное управление размерами UIView - Objective-C

28.07.2013, 16:23. Просмотров 2323. Ответов 9
Метки нет (Все метки)

итак начнем с того, что нам предоставляет ObjC из коробки

[view setFrame:(CGRect) rect];

метод мгновенно установит параметры прямоугольника области view

и свойство view.frame

по нему можно прочесть параметры размера или записать через view.frame=rect новое значение

управление автоматическим выравниванием

Название: xrcT4.png
Просмотров: 440

Размер: 1.5 Кб

и тут все относительно просто

работаем через бинарное сложение флагов для установки нужного выравнивания

Objective-C
1
2
3
mySubview.autoresizingMask = (UIViewAutoresizingFlexibleWidth |    
                              UIViewAutoresizingFlexibleLeftMargin |  
                              UIViewAutoresizingFlexibleRightMargin);
---
казалось бы все достаточно просто, однако когда начинаешь с этим работать вплотную, то всплывают некоторые "недостатки" этих методов

1) размер

для размера используется СИ структура из 2 подстуктур
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct CGRect {
  CGPoint origin;
  CGSize size;
};
 
struct CGSize {
  CGFloat width;
  CGFloat height;
};
 
struct CGPoint {
  CGFloat x;
  CGFloat y;
};
это означает то, чтобы добраться скажем до ширины, нужно написать view.frame.size.width

то есть используем ветку size

все бы и неплохо, но когда требуется присвоить вот тут и начинаются "пляски"

конструкция view.frame.size.width = 4; не компилируется

для того чтобы присвоить, нужно выделить frame в отдельную область памяти, изменить его и !только! потом можно присвоить размер.

На практике это выглядит так

Objective-C
1
2
3
CGRect newframe = view.frame;
newframe.size.width = 4;
view.frame = newframe;
целых 2 лишних строки кода на простую манипуляцию размером.

поэтому для повышения чистоты кода нужно написать несколько дополнительных свойств к UIView

UIView+Sizing.h
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
@interface UIView (Sizing)
 
@property (nonatomic, assign) float height;
@property (nonatomic, assign) float width;
@property (nonatomic, assign) float posX;
@property (nonatomic, assign) float posY;
@property (nonatomic, readonly) float right;
@property (nonatomic, readonly) float bottom;
@property (nonatomic, assign) float top;
@property (nonatomic, assign) float left;
 
@end
после добавления категории в проект, управление размерами упрощается

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// изменяем координату x
 
view.posX = 12;
 
// считываем координату y
 
float y = view.posY;
 
// устанавливаем размер по ширине
 
view.with = 50;
 
// перемещение относительно Y вниз на 20px :D
 
view.posY += 20;
 
// << сравнение перегруженного кода
 
// обычный
view.frame = CGRectMake(view2.frame.origin.x+view3.origin.x, 150, view2.size.width, view2.size.height);
// через класс категорию
view.frame = CGRectMake(view2.posX+view3.posX, 150, view2.width, view2.height);
2) "эффект половинного пикселя"

эффект половинного пикселя связан с тем что размеры и координаты UIView являются дробными числами

теперь программно зададим дробную координату

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// первый
UILabel*lab = [[UILabel alloc] initWithFrame:CGRectMake(10.5f, 10.5f, 200, 40)];
    lab.text = @"Hello world";
    
    [lab setBackgroundColor:[UIColor blackColor]];
    
    [lab setFont:[UIFont fontWithName:@"Times New Roman" size:30]];
    [lab setTextColor:[UIColor whiteColor]];
    
    [self.view addSubview:lab];
 
 // второй
    UILabel* lab2 = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 10.0f+40, 200, 40)];
    lab2.text = @"Hello world";
    
    [lab2 setBackgroundColor:[UIColor blackColor]];
    
    [lab2 setFont:[UIFont fontWithName:@"Times New Roman" size:30]];
    [lab2 setTextColor:[UIColor whiteColor]];
    
    [self.view addSubview:lab2];
Программное управление размерами UIView
чтобы избежать его достаточно просто округлять координаты при присвоении.

или можно внести изменения в класс категорию, огородив таким образом размеры UIView от дробных чисел

UIView+Sizing.h
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
@interface UIView (Sizing)
 
@property (nonatomic, assign) int height;
@property (nonatomic, assign) int width;
@property (nonatomic, assign) int posX;
@property (nonatomic, assign) int posY;
@property (nonatomic, readonly) int right;
@property (nonatomic, readonly) int bottom;
@property (nonatomic, assign) int top;
@property (nonatomic, assign) int left;
 
@end

2) авторазмер

тут есть одна тонкость, которую сразу увидеть нельзя.

во первых угадайте какому состоянию авторазмера соответствует эта картинка?

Название: Снимок экрана 2013-07-28 в 2.46.22 PM.png
Просмотров: 436

Размер: 5.3 Кб

а вот эта

Название: Снимок экрана 2013-07-28 в 2.47.14 PM.png
Просмотров: 439

Размер: 5.3 Кб

ответы:

Кликните здесь для просмотра всего текста
1) UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight

2) UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin


удивлены? а все дело в том что полностью включенная картинка не означает, что должны использоваться все флаги

какая же картинка соответствует всем включенным флагам?

вот эта
Кликните здесь для просмотра всего текста
Название: Снимок экрана 2013-07-28 в 2.54.19 PM.png
Просмотров: 436

Размер: 5.3 Кб


вывод из этого такой что флаги _LeftMargin,_BottomMargin,_RightMargin,_TopMargin являются флагами инверсии по отношению к тому что изображено на картинке, то есть присутствие флага означает выключение

Это была теория, перейдем к практике

Возьмем самый безнадежный случай, когда нам надо включить все флаги.

view.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
код перегружен выражением UIViewAutoresizingFlexible

выход из ситуации? есть.

добавим в класс категорию метод установки маски через логические флаги вместо enum сложения

Objective-C
1
2
3
4
5
6
-(void) setAutoresizingMaskFlexibleTop:(bool) Top
                                  Left:(bool) Left
                                Bottom: (bool) Bottom
                                 Right:(bool) Right
                                 Width: (bool) Width
                                Height: (bool) Height;
теперь если нужно включить все флаги или один из них достаточно вызвать

Objective-C
1
[view setAutoresizingMaskFlexibleTop:YES Left:YES Bottom:YES Right:YES Width:YES Height:YES];
причем теперь не надо вспоминать эти самые флаги, поскольку эта функции их полностью заменяет.

Важно только помнить, что флаги положения имеют инверсию в отличие от флагов размера.
Вложения
Тип файла: zip test_position_user_manual.zip (41.1 Кб, 8 просмотров)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.07.2013, 16:23     Программное управление размерами UIView
Посмотрите здесь:

Delphi Управление размерами форм и компанентов внутри
Visual Basic Word: вставка объектов и управление их положением и размерами
Управление размерами субформы MS Access
Управление размерами InputBox и MsgBox VBA
Управление размерами диалогового окна, контроль ввода числовых данных и т.д. VBA
Управление размерами формы Visual Basic
Программное обеспечение для Objective-C Objective-C
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
28.07.2013, 19:03     Программное управление размерами UIView #2
Цитата Сообщение от noname_club Посмотреть сообщение
@property (nonatomic, assign) int height;
@property (nonatomic, assign) int width;
@property (nonatomic, assign) int posX;
@property (nonatomic, assign) int posY;
@property (nonatomic, readonly) int right;
@property (nonatomic, readonly) int bottom;
@property (nonatomic, assign) int top;
@property (nonatomic, assign) int left;
Сами Вы int. Хотите округлять - используйте функции округления.
картинку напоминает

view.frame.size.width
CGRectGetWidth(view.frame);
Ваше "шаманство" опять уходит в сторону от стандарта.

иии... чтож Вы не написали, как нужно все геттеры сеттеры переопределить?

Цитата Сообщение от noname_club Посмотреть сообщение
тут есть одна тонкость, которую сразу увидеть нельзя.
во первых угадайте какому состоянию авторазмера соответствует эта картинка?
Угадать? Оо это же очевидно... все стороны привязаны к супервью, при этого будет иметь место растягивание данной вью. Там даже рядом картинка с анимацией есть.
Цитата Сообщение от noname_club Посмотреть сообщение
а вот эта
Тоже рядом нарисовано все.

Цитата Сообщение от noname_club Посмотреть сообщение
Возьмем самый безнадежный случай, когда нам надо включить все флаги.
view.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
Вообще для таких случаев и разработан Interface Builder, чтобы уменьшить писанину. А вы советуете, насколько я понял из данного поста, им не пользоваться.

удивлены? а все дело в том что полностью включенная картинка не означает, что должны использоваться все флаги
Нет конечно, на то они и Flexible.

Цитата Сообщение от noname_club Посмотреть сообщение
добавим в класс категорию метод установки маски через логические флаги вместо enum сложения
UIViewAutoresizingNone, религия не позволяет?
И Да, конечно, лучше юзать ужасно названный метод, автор которого даже на стандарт наименования плюет.
Цитата Сообщение от noname_club Посмотреть сообщение
вместо enum сложения
Там не enum. Там bitfield. Разницу понимаете?

Полная безграмотность на лицо. А еще пытаетесь учить и советовать.
Если я не ошибаюсь, Это уже Ваш 3й подобный пост. Но вы не останавливайтесь. Чем больше такого кода и понимающих людей, тем лучше у меня с работой
Vorona
Peace 2 all shining faces
666 / 528 / 44
Регистрация: 05.03.2010
Сообщений: 1,271
28.07.2013, 19:05     Программное управление размерами UIView #3
Цитата Сообщение от zulkis Посмотреть сообщение
Чем больше такого кода, тем лучше у меня с работой
ахах это точно

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

постите тут вопросы, пожалуйста, а умничайте у себя на странице, так будет более толерантно к другим пользователям форума
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
28.07.2013, 19:33     Программное управление размерами UIView #4
А мне он иногда нравится. Когда настроение есть. Забавный такой, неунывающий. А когда на работе юниоры или D2 чем-нибудь особенным отличатся, откроешь такую вот страничку, посмотришь на код и понимаешь, что у тебя в общем-то неплохие ребята в команде. И на душе радостно...
zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
28.07.2013, 20:48     Программное управление размерами UIView #5
mobidevelop, и добавить нечего
КОЗАК СЕРГІЙ
4 / 4 / 1
Регистрация: 16.10.2009
Сообщений: 38
31.07.2013, 12:37     Программное управление размерами UIView #6
mobidevelop,
glvrzzz
95 / 71 / 12
Регистрация: 12.12.2012
Сообщений: 214
16.09.2013, 10:19     Программное управление размерами UIView #7
noname_club, мне вот интересно, вы своими постами, всех чему-то научить пытаетесь? Эти ваши удивления и разоблачения по поводу autoresizingMask - это просто прелесть.
Поддерживаю zulkis и mobidevelop, продолжайте, мне тоже очень нравятся ваши посты, столько блестящих нелепых решений несуществующих проблем!

А если серьезно, правильно Vorona сказал, если у вас возникает проблема, вы для начала погуглите (большая часть проблем решена до вас), поспрашивайте более опытных ребят, либо у себя в команде, либо здесь.

А мне он иногда нравится. Когда настроение есть. Забавный такой, неунывающий. А когда на работе юниоры или D2 чем-нибудь особенным отличатся, откроешь такую вот страничку, посмотришь на код и понимаешь, что у тебя в общем-то неплохие ребята в команде. И на душе радостно...
А вот тут я не совсем согласен, есть у парня одна хорошая черта - инициатива и стремление хоть что-то оптимизировать, сделать лучше (пока, откровенно скажу, ну просто НИХРЕНА у него не получается, но с опытом возможно придет). Мне в отделе таких ребят не хватает, потому что, у таких, как правило, больше потенциал, чем у тех, которые сидят и тупо кодят "от забора и до обеда".
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 581
16.09.2013, 11:15  [ТС]     Программное управление размерами UIView #8
ну просто НИХРЕНА у него не получается
если вам не нравится пользоваться сабжем просто пройдите мимо, либо предложите как улучшить. И не надо говорить что "святой Стив" уже все придумал и это удобно. Конструкции избыточны это факт, но их не укорачивают ибо стандарт.

Написание классов категорий входит в средства языка, и поэтому может быть использовано для оптимизации написания кода.
glvrzzz
95 / 71 / 12
Регистрация: 12.12.2012
Сообщений: 214
16.09.2013, 11:26     Программное управление размерами UIView #9
если вам не нравится пользоваться сабжем
Не то что пользоваться, мне на него смотреть больно.
просто пройдите мимо, либо предложите как улучшить. И не надо говорить что "святой Стив" уже все придумал и это удобно.
Я как-нибудь сам решу, где мне мимо проходить и где и что писать. Если что-то постите, будьте готовы к критике.
Написание классов категорий входит в средства языка, и поэтому может быть использовано для оптимизации написания кода.
Тут я не понял, что вы имеете в виду
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.09.2013, 11:27     Программное управление размерами UIView
Еще ссылки по теме:

Objective-C Управление картинками
C# WPF Управление размерами
C++ Qt Управление размерами виджетов
Создание UIView внутри UIScrollView программно Objective-C
[MATE] Быстрое управление размерами и расположением окон приложений

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

Или воспользуйтесь поиском по форуму:
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
16.09.2013, 11:27     Программное управление размерами UIView #10
Цитата Сообщение от glvrzzz Посмотреть сообщение
А вот тут я не совсем согласен, есть у парня одна хорошая черта - инициатива и стремление хоть что-то оптимизировать, сделать лучше (пока, откровенно скажу, ну просто НИХРЕНА у него не получается, но с опытом возможно придет). Мне в отделе таких ребят не хватает, потому что, у таких, как правило, больше потенциал, чем у тех, которые сидят и тупо кодят "от забора и до обеда".
Воот. Сами же сказали. В отделе. А этот сам по себе, похоже, развивается. Если в ближайшее время не попадет в правильные руки, это все только усугубится.

Цитата Сообщение от noname_club Посмотреть сообщение
если вам не нравится пользоваться сабжем просто пройдите мимо, либо предложите как улучшить
Вот зря такая реакция. Вам помочь пытаются (хотя, если честно, надоедает уже одно и то же повторять), а вы уперлись как рогатое парнокопытное в свои сокращения и абсолютно не слушаете других людей, к тому же гораздо более опытных. Почему тогда удивляетесь, что не слушают вас?
Хор. Ещ 1 прмр. Удобно так. текс чит? пнятнее? ясн чт кроче. Но пнятнее? В общ прчит можн а нрав?
Yandex
Объявления
16.09.2013, 11:27     Программное управление размерами UIView
Ответ Создать тему
Опции темы

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