.Net开发人员是Objective-C的新手。需要一些批评和建议

时间:2010-06-25 17:08:30

标签: objective-c iphone-sdk-3.0

我使用Objective-C创建了我的第一个应用程序之一。作为一个菜鸟,我想做很多事情,但不知道如何在Objective-C中应用它。请看下面的方法(我从头开始创建)并告诉我你要做些什么来使它变得更好。显然我已经在两个UILabel上复制了代码,但我想简化它(我讨厌重复代码),但我不知道最好的方法是什么。我只需要一些建议,这些建议可以帮助我更好地理解在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 个答案:

答案 0 :(得分:4)

第一步,独立于您使用的语言,将遵循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 :(得分:1)

我将在评论中回答提问者提出的另一个问题。引用:

  

如果我想在该数组中使用混合类型怎么办?即一对UILabel和一对UIImageView。有没有办法比较类型或使用泛型?对于(对象中的NSObject * obj){if(label.type == UILabel)[self relocateLabel:obj],这是一个糟糕的猜测/示例; else if(label.type == UIImageView)[self relocateImage:obj]; }

正如Georg Fritzsche在那里回答的那样,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:)获取该邮件。

在诸如Georg发布的循环中,您通常只想检查目标对象是否响应选择器,否则将抛出异常,而Objective-C代码很少捕获异常作为正常代码流的一部分(与Python开发人员相反)。