2013-03-18 3 views
9

Я думал, что может быть способ легко скрыть и показать кнопку в строке с использованием автоматической компоновки, чтобы виды могли автоматически упорядочиваться аккуратно в зависимости от того, какие из них видны.Изящно скрывая и показывая виды при использовании автозапуска

Например, у меня есть две кнопки, которые я всегда хочу, сосредоточенные в кадре:

// pseudo visual format code: 
|-----[star][download]-----| 

Когда я нажимаю скачать я хочу сейчас, чтобы увидеть три кнопки: (pause кнопка download этикетки для; cancel является ранее скрытые кнопки)

|--[star][cancel][pause ]--|

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

+0

Я задал подобный вопрос и получил downvoted http://stackoverflow.com/ Вопросы/20876664/ios-autolayout-dynamic-adjust-controls/20876746? noredirect = 1 # comment31327381_20876746 :) – Abhishek

ответ

0

Я собрал небольшой образец, показывающий, как это может быть сделано с помощью пользовательской UIView подкласса. В приведенном ниже примере я использовал AutoLayout framework от this answer, и я бы рекомендовал вам сделать то же самое; он держит код ограничения чистым и разборчивым.

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

мой взгляд объявлен следующим образом:

@protocol TSDownloadViewDelegate; 
@interface TSDownloadView : UIView 
    @property (strong, nonatomic)   id<TSDownloadViewDelegate> delegate; 
@end 

@protocol TSDownloadViewDelegate <NSObject> 
    - (void) downloadStartedInDownloadView:(TSDownloadView*)downloadView; 
    - (void) downloadPausedInDownloadView:(TSDownloadView *)downloadView; 
    - (void) downloadCancelledInDownloadView:(TSDownloadView*)downloadView; 
@end 

И реализован так:

#import "UIView+AutoLayout.h" 
#import "TSDownloadView.h" 

static const CGFloat  kMargin    = 20.0; 

@interface TSDownloadView() 

    // Our buttons 
    @property (strong, nonatomic)   UIButton * starButton; 
    @property (strong, nonatomic)   UIButton * cancelButton; 
    @property (strong, nonatomic)   UIButton * downloadButton; 

    // State tracking 
    @property (nonatomic)     BOOL   downloading; 
    @property (nonatomic)     BOOL   constraintsUpdated; 

    // The constraint governing what's tied to the right hand side of the starButton 
    @property (weak, nonatomic)   NSLayoutConstraint *starRightConstraint; 

    // The constraint governing what's tied to the left hand side of the downloadButton 
    @property (weak, nonatomic)   NSLayoutConstraint *downloadLeftConstraint; 

@end 

@implementation TSDownloadView 

- (void) initializator 
{ 
    _starButton = [UIButton buttonWithType:UIButtonTypeSystem]; 
    _cancelButton = [UIButton buttonWithType:UIButtonTypeSystem]; 
    _downloadButton = [UIButton buttonWithType:UIButtonTypeSystem]; 

    _starButton.translatesAutoresizingMaskIntoConstraints = NO; 
    _cancelButton.translatesAutoresizingMaskIntoConstraints = NO; 
    _downloadButton.translatesAutoresizingMaskIntoConstraints = NO; 

    _starButton.titleLabel.textAlignment = NSTextAlignmentCenter; 
    _cancelButton.titleLabel.textAlignment = NSTextAlignmentCenter; 
    _downloadButton.titleLabel.textAlignment = NSTextAlignmentCenter; 

    [_starButton setTitle:@"Star" forState:UIControlStateNormal]; 
    [_cancelButton setTitle:@"Cancel" forState:UIControlStateNormal]; 
    [_downloadButton setTitle:@"Download" forState:UIControlStateNormal]; 

    [_downloadButton addTarget:self action:@selector(downloadClicked:) forControlEvents:UIControlEventTouchUpInside]; 

    [self addSubview:_starButton]; 
    [self addSubview:_cancelButton]; 
    [self addSubview:_downloadButton]; 

    _cancelButton.hidden = YES; 

} 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code 
     [self initializator]; 
    } 
    return self; 
} 

- (id) initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder:aDecoder]; 
    if(self) 
    { 
     [self initializator]; 
    } 
    return self; 
} 


- (void)downloadClicked:(id)sender 
{ 
    self.downloading = !self.downloading; 
    if(self.downloading) 
    { 
     [self.downloadButton setTitle:@"Pause" forState:UIControlStateNormal]; 
     self.cancelButton.hidden = NO; 

     // Remove previous constraints 
     [self removeConstraint:self.starRightConstraint]; 
     [self removeConstraint:self.downloadLeftConstraint]; 

     // |--[star][cancel][pause ]--| 
     self.starRightConstraint = [self.starButton autoPinEdge:ALEdgeRight toEdge:ALEdgeLeft ofView:self.cancelButton withOffset:-kMargin]; 
     self.downloadLeftConstraint = [self.downloadButton autoPinEdge:ALEdgeLeft toEdge:ALEdgeRight ofView:self.cancelButton withOffset:kMargin]; 

     // Tell delegate what's happened 
     if(self.delegate) 
      [self.delegate downloadStartedInDownloadView:self]; 
    } 
    else 
    { 
     [self.downloadButton setTitle:@"Download" forState:UIControlStateNormal]; 
     self.cancelButton.hidden = YES; 

     // Remove previous constraints 
     [self removeConstraint:self.starRightConstraint]; 
     [self removeConstraint:self.downloadLeftConstraint]; 

     // |-----[star][download]-----| 
     self.starRightConstraint = [self.starButton autoPinEdge:ALEdgeRight toEdge:ALEdgeLeft ofView:self.downloadButton withOffset:-kMargin]; 
     self.downloadLeftConstraint = nil; 

     // Tell delegate what's happened 
     if(self.delegate) 
      [self.delegate downloadPausedInDownloadView:self]; 
    } 

} 

- (void) updateConstraints 
{ 
    [super updateConstraints]; 
    if(self.constraintsUpdated) return; 
     self.constraintsUpdated = YES; 

    // Now put our constraints in place 

    // Make sure the button hugs the label and doesn't get stretched 
    // just because there's space available 
    [self.starButton setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; 

    // Pin the starButton to the top, left and bottom edges of its superview 
    [self.starButton autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:kMargin]; 
    [self.starButton autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:kMargin]; 
    [self.starButton autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:kMargin]; 

    // Repeat for the other buttons 

    [self.cancelButton setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; 
    [self.cancelButton autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:kMargin]; 
    [self.cancelButton autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:kMargin]; 

    [self.downloadButton setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; 
    [self.downloadButton autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:kMargin]; 
    [self.downloadButton autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:kMargin]; 
    [self.downloadButton autoPinEdgeToSuperviewEdge:ALEdgeRight withInset:kMargin]; 


    // These two are special. We keep a reference to them so we can replace 
    // them later. Note that since the cancelButton is hidden at the start, 
    // the initial value for downloadLeftConstraint is simply nil. 

    self.starRightConstraint = [self.starButton autoPinEdge:ALEdgeRight toEdge:ALEdgeLeft ofView:self.downloadButton withOffset:-kMargin]; 
    self.downloadLeftConstraint = nil; 
} 
@end 

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

0

Создайте (5) кнопки один над другим, используя автозапуск.

// на ViewDidLoad: набор отменить & кнопку паузы, чтобы скрыть

-(void) viewDidLoad 
{ 
    [_pauseBtn setHidden:YES]; 
    [_cancelBtn setHidden:YES]; 
} 

// на действия Downlaod

-(IBAction) downloadClick (UIButton *) sender 
{ 
    [_pauseBtn setHidden:NO]; 
    [_cancelBtn setHidden:NO]; 
    [sender setHidden:YES]; 
} 
Смежные вопросы