Как создать и вызвать подклассы UIView без использования пера - PullRequest
1 голос
/ 05 февраля 2010

Без использования Interface Builder или файлов XIB, как правильно создать экземпляры двух классов, которые наследуются от UIView, чтобы они могли переключаться между собой с помощью кнопок UIB, расположенных на самих представлениях?

Я думаю, что это включает в себя настройку UIViewController из делегата приложения и добавление двух экземпляров моих классов, которые реализуют UIView в контроллер (возможно, изнутри контроллера?)

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

Кроме того, мне интересно, если использование UIViewController необходимо, должен ли метод switch находиться в области действия основного делегата приложения?

Некоторые примеры кода были бы великолепны!

Ответы [ 3 ]

7 голосов
/ 05 февраля 2010

Ваша главная проблема в том, что вы концептуально не понимаете роль UIViewControllers по сравнению с UIViews. Большинство людей не делают, когда они только начинают.

Представления глупы и в идеале они должны состоять из общих объектов. Они не содержат практически никакой логики интерфейса. Они не знают или не заботятся о существовании других взглядов. Единственная логика, которую вы вводите в представления, - это логика, которая относится к немедленному и общему функционированию самого представления, независимо от того, какие данные оно отображает, или состояния других частей приложения. Вам редко нужно создавать подкласс UIView. Вот почему представления могут быть полностью настроены в Интерфейсном Разработчике без какого-либо кода.

ViewControllers содержат логику интерфейса и подключают интерфейс к данным (но они не содержат и не логически манипулируют данными.) Они «интеллектуальны» и хорошо настроены. ViewControllers действительно понимают место представления в контексте приложения. ViewControllers загружают и конфигурируют представления либо из пера, либо программно. ViewControllers управляют отображением или скрытием представлений и их порядком. ViewControllers определяют, какие действия предпринимаются в ответ на события и какие данные где отображаются.

Пример кода VictorB показывает, как все это делается прагматично. Важно отметить, что viewController и view являются полностью отдельными объектами от двух совершенно разных классов. Нет перекрытия и нет необходимости создавать подклассы UIView. Все настройки находятся в контроллере.

Все это из-за дизайна MVC. Он отделяет интерфейс от модели данных, делая их как модульными, так и независимыми друг от друга. Это облегчает проектирование, отладку и повторное использование каждого независимого модуля.

4 голосов
/ 05 февраля 2010

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

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

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

ToggleViewController.h:

#import <UIKit/UIKit.h>
@interface ToggleViewController : UIViewController {
    UIView *firstView;
    UIView *secondView;
    UIButton *button;
}
- (void)addButton;
- (void)toggleViews;
@property (nonatomic, readonly) UIView* firstView;
@property (nonatomic, readonly) UIView* secondView;
@property (nonatomic, readonly) UIButton* button;
@end

ToggleViewController.m:

#import "ToggleViewController.h"
@implementation ToggleViewController

// assign view to view controller
- (void)loadView {
    self.view = self.firstView;
}

// make sure button is added when view is shown
- (void)viewWillAppear:(BOOL)animated {
    [self addButton];

}

// add the button to the center of the view
- (void)addButton {
    [self.view addSubview:self.button];
    button.frame = CGRectMake(0,0,150,44);
    button.center = self.view.center;
}

// to toggle views, remove button from old view, swap views, then add button again
- (void)toggleViews {
    [self.button removeFromSuperview];
    self.view = (self.view == self.firstView) ? self.secondView : self.firstView;
    [self addButton];
}

// generate first view on access
- (UIView *)firstView {
    if (firstView == nil) {
        firstView = [[UIView alloc] initWithFrame:CGRectZero];
        firstView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        firstView.backgroundColor = [UIColor redColor];
    }
    return firstView;
}

// generate second view on access
- (UIView *)secondView {
    if (secondView == nil) {
        secondView = [[UIView alloc] initWithFrame:CGRectZero];
        secondView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        secondView.backgroundColor = [UIColor blueColor];
    }
    return secondView;
}

// generate button on access
- (UIButton *)button {
    if (button == nil) {

        // create button
        button = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];

        // set title
        [button setTitle:@"Toggle Views" 
                forState:UIControlStateNormal];

        // set self as a target for the "touch up inside" event of the button
        [button addTarget:self 
                   action:@selector(toggleViews) 
         forControlEvents:UIControlEventTouchUpInside];
    }
    return button;
}

// clean up
- (void)dealloc {
    [button release];
    [secondView release];
    [firstView release];
    [super dealloc];
}

@end
0 голосов
/ 05 февраля 2010

Используйте Interface Builder. Это по причине.

...