Встроенный блок при создании структуры

Это для обучения =) Я понимаю, что функции, методы и блоки могут быть объявлены и затем вызваны. Я просто пытаюсь понять блоки лучше.

Это основная идея того, что я хочу сделать.

CGRectMake(100,^CGFloat(){return 1.0f;},100,100);

Компилятор не видит возвращаемое значение блока и вместо этого видит сам блок как значение, которое приводит к ошибке. Я попробовал несколько способов приведения блока, но не смог найти решение.

Есть ли способ сделать это, и если да, то как? Если нет, есть ли другой способ сделать встроенную функцию с возвращаемым значением?

Редактировать Вот пример кода, который я использую, основываясь на правильных ответах.

valueLabelMin.frame = CGRectMake(0,
                                 ^CGFloat(){
                                   if (CGRectGetMaxY(dateRangeStartLabel.frame)) {
                                     return CGRectGetMaxY(dateRangeStartLabel.frame)-20;
                                   }else{
                                     return self.bounds.size.height-20;
                                   }
                                 }(),
                                 50,
                                 20);

Редактировать 2 Это немного выходит за рамки исходного вопроса, но демонстрирует его актуальность в контексте, который я всегда ценю при чтении вопросов.

Этот пример кода изменяет кадр некоторых UILabels в зависимости от условий, при желании анимируется и выполняет блок завершения.

Обратите внимание, что каждый ярлык setFrame вызывается только один раз, что приводит к очень управляемому коду =D Надо сказать, что версия "до" была таким беспорядком, что я не могу заставить себя ее включить.

- (void)updateValueRangeLabels:(BOOL)animated completion:(void(^)(void))completion {

    void (^setLabelFrames)() = ^()
    {
        valueLabelMax.frame = CGRectMake(^CGFloat(){if(_showValueRange){return 0;}else{return -50;}}(),
                                         CGRectGetMaxY(titleLabel.frame),
                                         50, 20);

        valueLabelMid.frame = CGRectMake(^CGFloat(){if(_showValueRange){return 0;}else{return -50;}}(),
                                         CGRectGetMaxY(titleLabel.frame) + (self.bounds.size.height - CGRectGetMaxY(titleLabel.frame) - CGRectGetMinY(dateRangeStartLabel.frame) - 20)/2,
                                         50, 20);

        valueLabelMin.frame = CGRectMake(^CGFloat(){if(_showValueRange){return 0;}else{return -50;}}(),
                                         ^CGFloat(){if(_showDateRange){return CGRectGetMinY(dateRangeStartLabel.frame)-20;}else{return self.bounds.size.height - 20;}}(),
                                         50, 20);
    };

    if (animated) {
        [UIView animateWithDuration:0.3 animations:^{
            setLabelFrames();
        }completion:^(BOOL finished){
            completion();
        }];
    }else{
        setLabelFrames();
        completion();
    }
}

Блоки потрясающие!

2 ответа

Решение

Оцените это так:

CGRect r = CGRectMake(100,^CGFloat(){return 1.0f;}(),100,100);
                                                  ^^

Еще один пример, представляющий параметр:

// creates a CGRect with all values set to the parameter (12 in this example)
CGRect r = ^CGRect(CGFloat p){return (CGRect){p,p,p,p};}(12);

гладкий

CGRect frame = view.frame;
frame.origin.x = 12;
view.frame = frame:

круглые скобки

view.frame = (CGRect frame = view.frame; frame.origin.x = 12; frame);

блок

view.frame = ^{CGRect frame = view.frame; frame.origin.x = 12; return frame; }();
Другие вопросы по тегам