Пользовательский вид UIPageControl, заменяющий точки на «Страница X из Y» - PullRequest
13 голосов
/ 14 мая 2009

Я пытаюсь найти способ заменить точки UIPageControl надписью, которая гласит «Страница X из Y», поскольку у меня, вероятно, будет> 50 элементов. Я только знакомлюсь с Какао, и мне было интересно, как лучше всего это сделать. Могу ли я создать подкласс UIPageControl? Должен ли я использовать пользовательский вид с метками? Или что-то еще?

Edit:

В итоге я использовал этот код Мэтта Галлахера для достижения моего просмотра страниц. Он также более эффективен, поскольку он использует два представления вместо того, чтобы создавать их все сразу, как это делается в примере кода Apple для PageControl.

Ответы [ 6 ]

27 голосов
/ 22 ноября 2010

РЕДАКТИРОВАТЬ:

Этот ответ получил несколько голосов. Спасибо, но для всех, кто пришел сюда, пожалуйста, поймите, что UIPageControl очень легко реализовать самостоятельно ! Более конкретно, взгляните на мой ответ и пример кода ниже для некоторых идей, но вы действительно не должны использовать его в производственном коде. Бросьте свой собственный подкласс UIControl, если вам нужно изменить внешний вид UIPageControl.


ОРИГИНАЛЬНЫЙ ОТВЕТ:

UIPageControl не делает ничего особенного. Для большинства представлений само представление либо делает все свои рисунки в drawRect: либо добавляет подпредставления, и те рисуют сами. Переопределяя drawRect: и не вызывая [super drawRect:], вы гарантируете, что, если реализация основана на drawRect: -b, у вас будет собственный код для рисования. В случае UIPageControl, он опирается на подпредставления, которые были добавлены в UIPageControl. Вы действительно не должны знать, какого рода, хотя и не должны заботиться. Это реализация Apple, и она может быть изменена.

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

Вот пример, который показывает, как создать свой собственный UIPageControl. Проницательный читатель заметит, что, как только вы решите сделать это таким образом, вы могли бы просто создать свой собственный элемент управления страницей в качестве подкласса UIControl и просто внедрить UIPageControl API.

//
//  RedGreyPageControl.m
//

@interface RedGreyPageControl : UIPageControl {
    NSArray                     *originalSubviews;
}

@end


@implementation RedGreyPageControl


// This assumes you're creating the control from a nib.  Depending on your
// usage you might do this step in initWithFrame:
- (void) awakeFromNib {
    // retain original subviews in case apple's implementation
    // relies on the retain count being maintained by the view's
    // presence in its superview.
    originalSubviews = [[NSArray alloc] initWithArray: self.subviews];

    for ( UIView *view in self.subviews ) [view removeFromSuperview];

    // make sure the view is redrawn not scaled when the device is rotated
    self.contentMode = UIViewContentModeRedraw;
}


- (void) dealloc {
    [originalSubviews release];
    [super dealloc];
}


- (void) drawRect:(CGRect) iRect {
    UIImage                 *grey, *image, *red;
    int                     i;
    CGRect                  rect;

    const CGFloat           kSpacing = 10.0;

    iRect = self.bounds;

    if ( self.opaque ) {
        [self.backgroundColor set];
        UIRectFill( iRect );
    }

    if ( self.hidesForSinglePage && self.numberOfPages == 1 ) return;

    red = [UIImage imageNamed: @"circle_graphic_red.png"];
    grey = [UIImage imageNamed: @"circle_graphic_grey.png"];

    rect.size.height = red.size.height;
    rect.size.width = self.numberOfPages * red.size.width + ( self.numberOfPages - 1 ) * kSpacing;
    rect.origin.x = floorf( ( iRect.size.width - rect.size.width ) / 2.0 );
    rect.origin.y = floorf( ( iRect.size.height - rect.size.height ) / 2.0 );
    rect.size.width = red.size.width;

    for ( i = 0; i < self.numberOfPages; ++i ) {
        image = i == self.currentPage ? red : grey;

        [image drawInRect: rect];

        rect.origin.x += red.size.width + kSpacing;
    }
}


// you must override the setCurrentPage: and setNumberOfPages:
// methods to ensure that your control is redrawn when its values change
- (void) setCurrentPage:(NSInteger) iPage {
    [super setCurrentPage: iPage];
    [self setNeedsDisplay];
}


- (void) setNumberOfPages:(NSInteger) iPages {
    [super setNumberOfPages: iPages];
    [self setNeedsDisplay];
}


@end
4 голосов
/ 15 мая 2009

Я не думаю, что написание пользовательского элемента управления страницей нарушит рекомендации по интерфейсу пользователя. Я думаю, что показ> 50 точек, хотя;)

Я думаю, что вполне приемлемо идти в обе стороны.

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

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

3 голосов
/ 28 мая 2009

Просто используйте UILabel и задайте его текст с форматной строкой в ​​делегате прокрутки, который говорит «Страница N из K» или что-то подобное. Невидимые кнопки влево / вправо могут быть добавлены с помощью простых прозрачных UIButton s.

На ваше усмотрение, если вы действительно хотите написать подкласс UIControl самостоятельно ...

2 голосов
/ 19 июня 2010

Кроме того, я должен добавить для всех, кто рассматривает создание подкласса UIPageControl (как я пришел сюда (к сожалению) после выполнения ), класс по какой-то тупой причине не делает свое рисование в drawRect: или любом другом публичный метод по этому вопросу. Я подозреваю, что в какой-то момент во время обновления страницы он устанавливает контекст рисования и заполняет его точками, но я здесь, чтобы предупредить вас:

  • Вы не можете переопределить drawRect: в UIPageControl, чтобы вы рисовали собственные точки вместо стандартных точек. Даже если вы нарисовали прямоугольник для рисования точек, UIPageControl всегда (ууу!) Будет рисовать свои маленькие белые точки.

Это делает класс практически не подклассифицированным. Конечно, вы могли бы, но почему?

И что еще более важно, , почему сделал бы Apple класс с таким смехотворно ненормальным поведением ?! drawRect: есть причина! Это напоминает мне о работе с NSMatrix в прежние времена…

1 голос
/ 15 мая 2009

Хотя вы можете создать подкласс UIPageControl, я не думаю, что он что-то добавит. Я предлагаю вам подкласс UIControll и основывать ваш API на API UIPAgeControl. Я думаю, что интерфейсы будут идентичны.

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

0 голосов
/ 18 февраля 2013

Я нашел хороший класс управления страницами: DDPageControl

Поведение такое же, как и у UIPageControl, и вы можете настроить его ...

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