Программное создание видов в IOS (как это работает)? - PullRequest
16 голосов
/ 27 января 2011

Немного предыстории: я просматриваю видео CS193P iTune, и я застрял в задании 3 надолго.По сути, задание просит вас программно создать пользовательский вид для отображения фигуры на экране.Кстати, я не использую никаких контроллеров представления.

Я не мог отобразить свое представление, пока, наконец, не перетащил объект View в Interface Builder и не изменил имя объекта на свой собственный класс представления.Поэтому мой вопрос: когда люди говорят, что программно создают представление, они просто говорят, что создают класс вручную, но когда вам нужно отобразить его, используйте IB?Я не могу избавиться от ощущения, что я что-то неправильно понял?

edit: позвольте мне быть более ясным.Мой пользовательский вид был инициализирован с рамкой 0, 0, 200, 150, и drawRect переопределяется, чтобы нарисовать в нем квадрат.Мой вид даже не отображается, если попытаться добавить его в главное окно в моем контроллере:

    UIWindow* window = [UIApplication sharedApplication].keyWindow;
[window addSubview:polygonView];

Однако, если использовать перетаскивание вида в IB и изменить класс на класс моего вида, он отображаетсяхорошо.

Редактировать: Добавлен код.Это метод awakeFromNib моего контроллера, где должно отображаться представление.

    - (void)awakeFromNib {
    shape = [[PolygonShape alloc] initWithNumberOfSides:numberOfSidesLable.text.integerValue minimumNumberOfSides:3 maximumNumberOfSides:12];
    polygonView = [[PolygonView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    polygonView.backgroundColor = [UIColor blackColor];
    [window addSubview:polygonView];
    [self updateInterface];  
}

Часть метода updateInterface моего контроллера:

- (void)updateInterface {
    [polygonView setPolygon:shape];
    [polygonView setNeedsDisplay];
...
}

PolygonView.h

#import <UIKit/UIKit.h>
#import "PolygonShape.h"

@interface PolygonView : UIView {
    IBOutlet PolygonShape *polygon; 
}

@property (readwrite, assign) PolygonShape *polygon;

- (void)drawRect:(CGRect)rect;
@end

PolygonView.m

#import "PolygonView.h"

@implementation PolygonView
@synthesize polygon;

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
        nslog(@"initialized");
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
       CGRect bounds = [self bounds];

    [[UIColor grayColor] set];
    UIRectFill(bounds);

    CGRect square = CGRectMake(10, 10, 10, 100);
    [[UIColor blackColor] set];
    UIRectFill(square);

    [[UIColor redColor] set];
    UIRectFill(square);
    NSLog(@"drawRect called");
}
@end

PolygonView инициализируется, но drawRect не вызывается.

Ответы [ 8 ]

17 голосов
/ 27 января 2011

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

UIWindow* window = [UIApplication sharedApplication].keyWindow;

UIView *polygonView = [[UIView alloc] initWithFrame: CGRectMake ( 0, 0, 200, 150)];
//add code to customize, e.g. polygonView.backgroundColor = [UIColor blackColor];

[window addSubview:polygonView];
[polygonView release];

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

viewController.view = polygonView;

Удачи!

4 голосов
/ 26 ноября 2011

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

Если вы сделали перо по отдельности (так, чтобы оно не было сделано для вас вместе с вашим классом), тогда вы должны помнитьщелкните UIViewController, который вы поместили в конструкторе интерфейсов, а затем на панели свойств нажмите кнопку третьей вкладки («Пользовательский класс»).Class будет базовым классом по умолчанию UIViewController и т. Д. - просто откройте этот выпадающий список, и вы увидите список всех ваших пользовательских подклассов, выберите его и volla - вы связали свой пользовательский элемент с интерфейсом.

Надеюсь, что кто-то спасет те дни, которые понадобились мне, чтобы понять, я нашел несколько тупо замечательных способов обойти это, пока не нашел простое решение.

2 голосов
/ 14 апреля 2012

привет, просто добавьте этот код,

[window bringSubviewToFront:polygonView];

right after,
 [window addSubview:polygonView];
2 голосов
/ 27 января 2011

Вам нужно иметь представление (или окно), чтобы добавить подпредставление. Обычный синтаксис выглядит так:

UIView *newView = [[UIView alloc] initWithFrame:mainView.bounds];
[mainView addSubview:newView];
[newView release];

Конечно, если у вас есть пользовательский объект, который наследуется от UIView, вы бы использовали его вместо UIView. Когда вы начинаете новый проект, создайте «Приложение на основе представления», которое запустит вас с контроллером представления со связанным представлением (к которому можно обратиться через «CustomViewController.view», который заменит «mainView» в фрагменте кода выше).

Если вы хотите создать представление программно при запуске приложения, поместите код в метод "- (void) viewDidLoad" вашего контроллера представления.

0 голосов
/ 05 июня 2013

звонок

[super drawRect];

перед вашим пользовательским кодом в drawRect: body.

0 голосов
/ 30 марта 2012

Недавно у меня была очень похожая проблема, и вот что сработало для меня: кажется, что при запуске с «пустым приложением» в Xcode 4.3.2 вы должны установить свое представление как корневое представление главного окна, используя метод setRootViewControllerвместо addSubview.Итак:

// Initialize myView and then
[window setRootViewController:myView];
// instead of [window addSubview:myView];
// the rest as normal...
[window makeKeyAndVisible];

После этого вы можете использовать метод addSubview для добавления дополнительных представлений.

0 голосов
/ 27 января 2011

Вы установили цвет фона вашего вида на что-то различимое?

Вы уверены, что ваш вид не отображается, или вы просто его не видите?Поместите NSLog в метод drawRect: вашего представления (если вы используете пользовательский класс представления).

0 голосов
/ 27 января 2011

Где-то в вашем активном классе контроллера вы можете добавить пользовательское представление к текущему представлению верхнего уровня.

[ myCurrentTopView addSubview: myNewCustomView ];

Помогает сначала выделить и инициализировать это пользовательское представление.

Затем вы можете запустить рисование в drawRect этого пользовательского представления, выполнив:

[ myNewCustomView setNeedsDisplay ];
...