.Net разработчик, новый для Objective-C.Нужна критика и предложения - PullRequest
1 голос
/ 25 июня 2010

Я создал одно из моих первых приложений, используя Objective-C. Будучи нубом, я хочу сделать много вещей, но не знаю, как применить их в Objective-C. Пожалуйста, посмотрите на метод ниже (который я создал с нуля) и скажите мне, что бы вы сделали, чтобы сделать его лучше. Очевидно, я продублировал код на двух UILabels, но я хотел бы упростить это (я ненавижу дублировать код), но я не знаю, каков наилучший способ сделать это. Мне просто нужны предложения, которые помогут мне лучше понять, как правильно делать вещи в Objective-C

timeText и dateText имеют тип UILabel

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (isRearranging)
    {
        NSLog(@"touchesMoved");
        NSLog(@"touches=%@,event=%@",touches,event);
        //TOUCH INFO
        UITouch *touch = [[touches allObjects] objectAtIndex:0];
        CGPoint currentLocation = [touch locationInView:touch.view];
        CGPoint previousLocation = [touch previousLocationInView:touch.view];
        //FRAME INFO
        float timeHalfWidth = timeText.frame.size.width / 2;
        float timeHalfHeight = timeText.frame.size.height / 2;
        CGRect timeTextRect = CGRectMake(timeText.center.x - (timeHalfWidth), timeText.cener.y - (timeHalfHeight), timeText.frame.size.width, timeText.frame.size.height);
        float dateHalfWidth = dateText.frame.size.width / 2;
        float dateHalfHeight = dateText.frame.size.height / 2;
        CGRect dateTextRect = CGRectMake(dateText.center.x - (dateHalfWidth), dateText.center.y - (dateHalfHeight), dateText.frame.size.width, dateText.frame.size.height);
        //IF TIME TEXT
        if(CGRectContainsPoint(timeTextRect,previousLocation))
        {
            CGPoint item = timeText.center;
            CGPoint diff;
            diff.x = previousLocation.x - item.x;
            diff.y = previousLocation.y - item.y;
            CGPoint newLoc;
            newLoc.x = currentLocation.x - diff.x;
            newLoc.y = currentLocation.y - diff.y;
            if (newLoc.x<timeHalfWidth)
                newLoc.x = timeHalfWidth;
            if (newLoc.y<timeHalfHeight)
                newLoc.y = timeHalfHeight;
            [timeText setCenter:(newLoc)];
        }
        //IF DATE TEXT
        if(CGRectContainsPoint(dateTextRect,previousLocation))
        {
            CGPoint item = dateText.center;
            CGPoint diff;
            diff.x = previousLocation.x - item.x;
            diff.y = previousLocation.y - item.y;
            CGPoint newLoc;
            newLoc.x = currentLocation.x - diff.x;
            newLoc.y = currentLocation.y - diff.y;
            if (newLoc.x<dateHalfWidth)
                newLoc.x = dateHalfWidth;
            if (newLoc.y<dateHalfHeight)
                newLoc.y = dateHalfHeight;
            [dateText setCenter:(newLoc)];      
        }
    }
    touchMoved = YES;
}

Большое спасибо за вашу помощь!

Ответы [ 2 ]

4 голосов
/ 25 июня 2010

Первым шагом, независимо от языка, на котором вы работаете, будет следовать DRY - большая часть вашего кода одинакова для обеих меток. Тогда уже есть функциональность для тестирования на попадание в SDK, например -hitTest:withEvent: или -pointInside:withEvent::

NSArray *labels = [NSArray arrayWithObjects:timeText, dateText, nil];
for (UILabel *label in labels) {
    if ([label pointInside:previousLocation withEvent:nil]) {
        [self relocateLabel:label]; 
        break;
    }
}
1 голос
/ 07 сентября 2011

Я отвечу на дополнительный вопрос, заданный asker в комментарии.Цитата:

Что если я захочу использовать смешанные типы в этом массиве?т.е. пара UILabel и пара UIImageView.Есть ли способ сравнить типы или использовать дженерики?Это плохое предположение / пример для (NSObject * obj в объектах) {if (label.type == UILabel) [self relocateLabel: obj];иначе if (label.type == UIImageView) [self relocateImage: obj];}

Как ответил Георг Фрицше, обмен сообщениями в Objective-C является динамическим.Объект будет «запрошен», если он поддерживает это сообщение во время выполнения, и если это так, он выполнит метод, связанный с сообщением.Имя метода / сообщения называется «селектором».

Если вы явно хотите выяснить класс объекта, вы также можете сделать это.

if([view isKindOfClass:[UILabel class]])
{
    // your code here
}

Если вы просто хотите выяснитьесли целевой объект отвечает на селектор (то есть реализует метод):

if([view respondsToSelector:@selector(relocateView:)])
{
    // your code here
}

Селекторы получают из имен методов, пропуская сами аргументы, оставляя двоеточия нетронутыми и добавляя все близко.Например, если у вас есть отправленное сообщение (то есть вызов метода): [thing moveTowardsObject:door movementType:XYZ_CRAWL], его селектор будет: moveTowardsObject:movementType:, и вы получите его, используя @selector(moveTowardsObject:movementType:).

В цикле, такомкак и то, что написал Георг, вы обычно хотите просто проверить, реагирует ли целевой объект на селектор, так как в противном случае было бы выброшено исключение, и код Objective C редко перехватывает исключения как часть нормального потока кода (в отличие от того, что разработчики Python).делает).

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