我使用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;
}
非常感谢你的帮助!
答案 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开发人员相反)。