Пользовательский режим UIPageControl, заменяющий точки "Страница X of Y",

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

Edit:

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

Ответы

Ответ 1

ИЗМЕНИТЬ:

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


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

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

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

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

//
//  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 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

Ответ 2

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

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

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

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

Ответ 3

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

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

Ответ 4

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

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

Это делает класс существенно не подкласса. Конечно, можно, но почему?

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

Ответ 5

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

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

Ответ 6

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

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