Как настроить subviews с AutoLayout в UIScrollView программно?
Я создаю приложение с UiScrollview и UIPagectontrol, используя Autolayout Progrmatically, для
Я создал TKScroller как подкласс UIView, я инициализирую его с помощью некоторого режима и массива.
TKScroller.m
-(void)setData{
[self layoutIfNeeded];
CGRect mainFrame=self.frame;
[self layoutIfNeeded];
CGRect mainFrame=self.frame;
UIView *lastview;
NSMutableArray* manualConstraints = [NSMutableArray array];
for (int i=0; i<arrayData.count ; i++)
{
CGRect frame;
frame.origin.x = scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = scrollView.frame.size;
UIView *subview = [UIView new];
subview.backgroundColor = [self getRandomColor];
[scrollView addSubview:subview];
if (i==0)
{
NSLayoutConstraint* b1_top = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:5];
[manualConstraints addObject:b1_top];
NSLayoutConstraint* b1_left = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeLeading multiplier:1 constant:5];
[manualConstraints addObject:b1_left];
NSLayoutConstraint* b1_right = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTrailing multiplier:1 constant:-5];
[manualConstraints addObject:b1_right];
NSLayoutConstraint* b1_bottom = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:-10];
[manualConstraints addObject:b1_bottom];
[subview layoutIfNeeded];
[scrollView addConstraints:manualConstraints];
lastview=subview;
}
else{
NSLayoutConstraint* b1_top = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:5];
[manualConstraints addObject:b1_top];
NSLayoutConstraint* b1_left = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:lastview attribute:NSLayoutAttributeLeading multiplier:1 constant:5];
[manualConstraints addObject:b1_left];
NSLayoutConstraint* b1_right = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTrailing multiplier:1 constant:-5];
[manualConstraints addObject:b1_right];
NSLayoutConstraint* b1_bottom = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:-10];
[manualConstraints addObject:b1_bottom];
[subview layoutIfNeeded];
[scrollView addConstraints:manualConstraints];
lastview=subview;
}
}
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * arrayData.count, mainFrame.size.height/2);
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = arrayData.count;
pageControlBeingUsed = NO;
}
-(UIColor *)getRandomColor{
int r = arc4random() % 255;
int g = arc4random() % 255;
int b = arc4random() % 255;
return [UIColor colorWithRed:(r/255.0) green:(g/255.0) blue:(b/255.0) alpha:1.0];
}
Сейчас я получаю какие-либо подзаголовки,
но если я изменю ориентацию, это даст неверный результат. Так как я могу дать NSLayoutConstraint
для подзаголовков scrollview?
ИЗМЕНИТЬ
После добавления NSLayoutConstraint
subviews не отображаются. Я просто пропущу какое-то ограничение, пожалуйста, исправьте меня при установлении ограничений динамически.
Мой Исходный код здесь. Пожалуйста, помогите мне.
Спасибо. И извините за плохую грамматику.
Ответы
Ответ 1
Вот ответ SO объяснил, как это сделать с автоматическим макетом, он прекрасно объясняет: здесь есть вертикальные текстовые поля, но в вашем случае это вам нужно установить ограничения горизонтального вида.
Alternative
Скорее это ограничение установки вы можете установить только кадр подвью и установить его в Scrollview, и на основе ориентации вы можете изменить кадры подпрограммы scrolview.
Ваш метод setData,
-(void)setData{
[self layoutIfNeeded];
CGRect mainFrame=scrollView.frame;
CGRect frame;
for (int i=0; i<arrayData.count ; i++)
{
CGRect frame;
frame.origin.x = scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = scrollView.frame.size;
frame.origin=CGPointMake(0, 0);
UIView *subview = [[UIView alloc]initWithFrame:frame];
subview.backgroundColor = [self getRandomColor];
[scrollView addSubview:subview];
}
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * arrayData.count, mainFrame.size.height/2);
}
Теперь вы используете NSNotificationCenter, вы можете получать уведомления о том, как настроить ориентацию устройства, поэтому в этом методе выбора вы вызываете свой метод setData
,
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(setData)
name:UIDeviceOrientationDidChangeNotification
object:nil];
Теперь, когда вы устанавливаете метод setData, вам нужно удалить все подзаголовки, потому что, когда устройство меняет ориентацию, оно добавит новые виды в ваш scrollview, поэтому удалите все subview из Scrollview перед установкой его фрейма,
[scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
Убедитесь, что вы удаляете наблюдателя из своего класса, например
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Ответ 2
В моем опыте с AutoLayout
(что я тоже использую программно). Не следует добавлять представления непосредственно к UIScrollView
.
Вы должны сделать один UIView
и только один, который вы добавите в качестве подзаголовка вашего UIScrollView
.
Как только это будет сделано, вы можете добавить все ваши подпрограммы к этому UIView
.
Здесь подробно объяснено: Техническая нота Apple iOS TN2154
Ответ 3
Я знаю, что проблема решена. и я надеюсь, что это решение поможет мне некоторым людям, поэтому я отправляю его.
Ниже приведен код для добавления прокрутки в uiviewcontroller
self.scrollView = UIScrollView()
self.scrollView.backgroundColor = UIColor.greenColor()
self.scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.scrollView.scrollEnabled=true
self.scrollView.pagingEnabled = true
self.view.addSubview(self.scrollView)
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["scrollView":self.scrollView]))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["scrollView":self.scrollView]))
После добавления scrollview и добавления подвью/изображений, подобных этому (это пример для изображений, отображаемых в полном размере scrollview, например, в приложении для фотографий)
var prev:UIImgeView?
for var index = 0; index < self.images.count; ++index {
var iview = UIImgeView()
iview.setTranslatesAutoresizingMaskIntoConstraints(false)
self.scrollView.addSubview(iview)
var image = self.images.objectAtIndex(index) as UIImage
iview.image = image
if (index == 0){
self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[iview(==scrollView)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"scrollView":self.scrollView]))
prev = iview
}
else{
self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[prev][iview(==prev)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"prev":prev!]))
prev = iview
}
self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[iview(==scrollView)]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"scrollView":self.scrollView]))
if (index == self.images.count-1){
self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[prev]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["prev":prev!]))
}
}
Ответ 4
Если вы хотите, чтобы ваш TKScroller был зафиксирован в центре и поддерживал изменения ориентации, вы можете просто поместить следующий код в свой init
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
и вам может потребоваться проверить все ваши подпрограммы TKScroller. Если вам не нравится автосоздание, вы можете установить (один из трех)
self.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;