2014-02-21 7 views
12

Я создаю приложение с UIScrollView и UIPagectontrol использования Autolayout Progrmatically дляКак настроить subviews с AutoLayout в UIScrollView программно?

Я создал TKScroller в качестве подкласса UIView, я инициализировать его с помощью некоторых режимов и Array.

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 подвидов не показаны. Я просто пропущу какое-то ограничение, пожалуйста, поправьте меня в установлении ограничений динамически.

Source Code is here, Пожалуйста, помогите мне. Спасибо. И извините за плохую грамматику.

+0

Что вы подразумеваете под «неправильным результатом»? – AncAinu

+0

@AncAinu: pageControl выходит из поля зрения. – user203108

+0

Прежде всего, если вы программно выполняете «AutoLayout», я советую вам [использовать эту отличную платформу] (https://github.com/iMartinKiss/KeepLayout), это сделает вашу жизнь намного проще, и ваш код будет настолько удобочитаемым ;) – AncAinu

ответ

6

Here is a SO answer объяснил, как сделать это с помощью автоматической компоновки, он объясняет отлично, в здесь есть вертикально текстовые поля там Но в в вашем случае вам нужно установить ограничения горизонтального представления.

Alternative

Скорее, что установка ограничений вы можете установить только рамку подвида и установить его в Scrollview, и на основе ориентации вы можете изменить кадры подвидов в scrolview в.

Ваш УстановитьДанные метод, как,

-(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 вы можете получить уведомления при ориентации устройства chaged, так что в этом методе селекторного его вызове метода setData,

[[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(setData) 
               name:UIDeviceOrientationDidChangeNotification 
               object:nil]; 

В настоящее время в вам необходимо установить метод setData, чтобы удалить все подзаголовки, потому что когда устройство изменит ориентацию, оно добавит новые виды в ваш scrollview, поэтому удалите все подвью из прокрутки до установки его рамки,

 [scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 

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

- (void)dealloc 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 
+0

Спасибо за повтор, но в каком методе мне нужно написать наблюдатель NSNotificationCenter'? – user203108

+0

Как вы говорите, это пользовательский класс, так что правильно в его методе 'init', вы реализовали этот метод? –

+0

Да, я написал '- (id) массив кадров initWithFrame: (CGRect): (NSMutableArray *) режим массива: (режим ScrollerMode) mode, – user203108

9

По моему опыту с AutoLayout (что я также использую программно). Не следует добавлять виды непосредственно к UIScrollView.

Вы должны сделать один UIViewи только один, что вы добавляете в подвид вашего UIScrollView.

Как только это будет сделано, вы можете добавить все свои подзоны к этому UIView.

Все объяснено подробно здесь: Apple iOS Technical Note TN2154

+0

Да, я делаю так, у меня есть UIView> UIScrollview', и в scrollview также я добавляю одно представление, а в ссылке ссылка имеет один вид, я должен добавить несколько просмотров в uiscrollview. – user203108

+1

Это не то, что я прочитал в вашем коде, вы делаете '[scrollView addSubview: subview];' в 'for', поэтому вы добавляете много просмотров в свой' UIScrollView' – AncAinu

+0

в ссылке, в которой они использовали 'NSLayoutConstraint' с * * constraintsWithVisualFormat **, я не могу это сделать в моем случае, поэтому я использовал другой способ NSLayoutConstraint. – user203108

0

Если вы хотите, чтобы ваш TKScroller прикрепляются к изменениям ориентации центра и поддержки, вы можете просто поставить следующий код в INIT

self.autoresizingMask = UIViewAutoresizingFlexibleWidth; 

и вы можете необходимо проверить все ваши подпрограммы TKScroller. Если вам не нравится AutoSize, вы можете установить (один из трех)

self.autoresizingMask = UIViewAutoresizingFlexibleRightMargin; 
self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; 
self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin; 
+0

Это полезно только для обратной совместимости (и с помощью 'setTranslatesAutoresizingMaskIntoConstraints: NO'), но я не думаю, что это то, что хочет OP. – Can

5

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

Ниже код для добавления Scrollview к 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!])) 

      } 

     } 
+0

Этот макет для просмотра с горизонтальной или вертикальной планировкой? – netshark1000

Смежные вопросы