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

Objective-C

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

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

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

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

[view setFrame:(CGRect) rect];

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

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

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

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

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

Размер: 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
Просмотров: 439

Размер: 5.3 Кб

а вот эта

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

Размер: 5.3 Кб

ответы:

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

2) UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin


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

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

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

Размер: 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];
причем теперь не надо вспоминать эти самые флаги, поскольку эта функции их полностью заменяет.

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

UIBezierPath vs UIView - Программирование iOS
Всем доброго времени суток! Мне нужен ваш совет по поводу отрисовки в UIVIew. У меня следующая ситуация: Есть мой кастомный класс...

UIView с PageController - Программирование iOS
Здравствуйте! Может кто подсказать в чем проблема, хочу сделать UIView с PageController(чтобы на одной вьюшке было 7 экранов) Делаю по...

Анимация UIView - Программирование iOS
Есть 3 view, которые лежат друг на друге вот так: |------------------| | 1 | | |-------------| | | | 2 ...

Constraints и размер UIView - Программирование iOS
У меня, допустим, есть UIView добавленная на родительскую View и к ней применены space constraints со всех четырех сторон, то есть она...

Прижать UIView к низу - Программирование iOS
Подскажите как в коде прижать UIView к низу родительской вьюшки?

Рекурсивное создание UIView - Программирование iOS
Здравствуйте! Подскажите как сделать рекурсивное создание 15 UIView, каждая новая view должна располагаться поверх предыдущей. Спасибо!

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
28.07.2013, 19:03 #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й подобный пост. Но вы не останавливайтесь. Чем больше такого кода и понимающих людей, тем лучше у меня с работой
0
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,283
28.07.2013, 19:05 #3
Цитата Сообщение от zulkis Посмотреть сообщение
Чем больше такого кода, тем лучше у меня с работой
ахах это точно

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

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

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

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

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

Цитата Сообщение от noname_club Посмотреть сообщение
если вам не нравится пользоваться сабжем просто пройдите мимо, либо предложите как улучшить
Вот зря такая реакция. Вам помочь пытаются (хотя, если честно, надоедает уже одно и то же повторять), а вы уперлись как рогатое парнокопытное в свои сокращения и абсолютно не слушаете других людей, к тому же гораздо более опытных. Почему тогда удивляетесь, что не слушают вас?
Хор. Ещ 1 прмр. Удобно так. текс чит? пнятнее? ясн чт кроче. Но пнятнее? В общ прчит можн а нрав?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.09.2013, 11:27
Привет! Вот еще темы с ответами:

Изменить содержимое UIView сдвигом - Программирование iOS
Добрый день. Проблема в следующем: в методе viewDidLoad основного ViewController-а создаётся объект типа myView:UIView //...

Вращение UIView по типу часовой стрелки - Программирование iOS
Всем доброго времени суток, собственно есть задача иммитировать часы, избараздив просторы интернета и IOS Documentation, у меня получилось...

Создание UIView внутри UIScrollView программно - Objective-C
Ув. форумчане - нужна помощь. Как работать с интерфейс билдером я разобрался - теперь есть задача сделать интерфейс из кода. Сейчас...

Свой UIView - в каком методе добавить KVO ? - Программирование iOS
Есть CustomView,наследник UIView, с кнопкой и индикатором. В коде другого класса использую этот вью и меняю видимость кнопки. При этом...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
16.09.2013, 11:27
Ответ Создать тему
Опции темы

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