此代码是否遵循标准的Objective-C和MVC约定?

时间:2013-06-01 17:25:27

标签: ios objective-c model-view-controller conventions

我在Objective-C中编写了一个基本应用程序,用于显示用户与图片的联系人。问题是,没有划分,我觉得我违反了某些标准。

所有东西都是通过一个主ViewController处理的,它主要在用户点击按钮(通过插座到IB)后开始工作。

//
//  ViewController.m
//  Future Take 4
//
//  Created by Rooz Mahdavian on 5/31/13.
//  Copyright (c) 2013 Rooz Mahdavian. All rights reserved.
//

#import "ViewController.h"
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#import <QuartzCore/QuartzCore.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(userAllowedForAccess)];
    singleTap.numberOfTapsRequired = 1;
    singleTap.numberOfTouchesRequired = 1;
    [[self.view viewWithTag:300] addGestureRecognizer:singleTap];
    [[self.view viewWithTag:300] setUserInteractionEnabled:YES];

    CGRect tempButton = [self.view viewWithTag:300].frame;
    tempButton.origin.y = self.view.frame.size.height/2 - 56;
    [self.view viewWithTag:300].frame = tempButton;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration: .4];
    [UIView setAnimationDelay: 0];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

    CGRect tempButton2 = [self.view viewWithTag:300].frame;
    tempButton2.origin.y += 90;
    [self.view viewWithTag:300].frame = tempButton2;

    [self.view viewWithTag:100].alpha = 1;

    [UIView commitAnimations];


}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


- (IBAction)userAllowedForAccess {
    NSLog(@"User Has Verified Contacts");


    UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0,0, 320, 55)];
    header.backgroundColor = [UIColor colorWithRed:34/255.0 green:34/255.0 blue:34/255.0 alpha:1];

    [header.layer setShadowColor:[UIColor colorWithRed:14/255.0 green:14/255.0 blue:14/255.0 alpha:.5].CGColor];
    [header.layer setShadowOpacity:0];
    [header.layer setShadowRadius:3.0];
    [header.layer setShadowOffset:CGSizeMake(2.0, 2.0)];

    [self.view addSubview:header];
    [self.view bringSubviewToFront:[self.view viewWithTag:100]];

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration: .7];
    [UIView setAnimationDelay: 0];


    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

    CGRect tempLogo = [self.view viewWithTag:100].frame;
    tempLogo.origin.y = -14;
    tempLogo.size.height = tempLogo.size.height/2.5;
    tempLogo.size.width = tempLogo.size.width/2.5;
    tempLogo.origin.x = 160 - tempLogo.size.width/2;
    [self.view viewWithTag:100].frame = tempLogo;

    CGRect tempButton = [self.view viewWithTag:300].frame;
    tempButton.size.width = tempButton.size.width * 2.5;
    tempButton.size.height = tempButton.size.height * 2.5;
    tempButton.origin.x = -((tempButton.size.width/2)-((tempButton.size.width * 2.5))/2);

    [self.view viewWithTag:300].frame = tempButton;
    [self.view viewWithTag:300].alpha = 0;


    [self.view viewWithTag:200].alpha = 0;
    [header.layer setShadowOpacity:1];

    [UIView commitAnimations];





    ABAddressBookRef addressBook = ABAddressBookCreate();
    UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 60, self.view.frame.size.width, self.view.frame.size.height)];




    __block BOOL accessGranted = NO;
    if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            accessGranted = granted;
            dispatch_semaphore_signal(sema);
        });
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    }


    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
    CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );


    int peopleInARow = 0;
    int maxPeopleInARow = 3;
    int positionFromTop = 20;
    int IMAGE_SIZE = 70;
    float animationOffset = .5;
    float animationOffsetChange = .3;
    float animationDuration = .5;
    int scaleOffset = 40;
    int screenWidth = 320;
    int startingPositionFromLeft = 26;
    int positionFromLeft = startingPositionFromLeft;
    int topOffset = 40;
    int leftOffset = 26;
    int numberOfRows = 0;


    UIView *contactContainer;
    UIImage* image;
    CALayer * l;
    NSString* name;
    NSString* lastName;
    NSString* firstName;
    UIImageView *newimageview;
    UILabel *label;
    UIView *contactImageContainer;



    for ( int i = 0; i < nPeople; i++ )
    {
        ABRecordRef person = CFArrayGetValueAtIndex( allPeople, i );
        firstName = (__bridge_transfer NSString*)ABRecordCopyValue(person,
                                               kABPersonFirstNameProperty);
        lastName = (__bridge_transfer NSString*)ABRecordCopyValue(person,
                                               kABPersonLastNameProperty);
         name = [NSString stringWithFormat:@"%@ %@", firstName, lastName];





        if(ABPersonHasImageData(person)){
            //NSLog(@"%@", name);
            image = [UIImage imageWithData:(__bridge NSData *)ABPersonCopyImageData(person)];

            //NSLog(@"Position %i", positionFromLeft);
            newimageview = [[UIImageView alloc] initWithFrame:CGRectMake(-scaleOffset/2, -scaleOffset/2, IMAGE_SIZE+scaleOffset, IMAGE_SIZE+scaleOffset)];
            newimageview.contentMode = UIViewContentModeScaleAspectFit;




            [newimageview setImage: image];


            contactContainer = [[UIView alloc] initWithFrame:CGRectMake(positionFromLeft, positionFromTop + 20, IMAGE_SIZE, 200)];
            contactImageContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, IMAGE_SIZE, IMAGE_SIZE)];
            contactImageContainer.clipsToBounds = YES;

            l = [contactImageContainer layer];
            [l setMasksToBounds:YES];
            [l setCornerRadius:IMAGE_SIZE/2];

            // You can even add a border
            [l setBorderWidth:0.0];
            [l setBorderColor:[[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:.6] CGColor]];


            [contactImageContainer addSubview:newimageview];







            [contactContainer addSubview:contactImageContainer];

            label =  [[UILabel alloc] initWithFrame: CGRectMake(0, IMAGE_SIZE + 10, IMAGE_SIZE, 20)];
            label.text = firstName;
            label.backgroundColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0];
            label.textColor = [UIColor whiteColor];
            [label setTextAlignment:NSTextAlignmentCenter];
            [label setFont:[UIFont fontWithName:@"Arial-BoldMT" size:14]];
            [contactContainer addSubview:label];


            contactContainer.alpha = 0;






            [UIView beginAnimations:nil context:nil];
            [UIView setAnimationDuration:animationDuration];
            [UIView setAnimationDelay:animationOffset];
            animationOffset+= animationOffsetChange;
            [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

            contactContainer.alpha = 1;
            CGRect temp = contactContainer.frame;
            temp.origin.y = positionFromTop;
            contactContainer.frame = temp;

            [UIView commitAnimations];

            if(peopleInARow >= 2){
                positionFromTop += IMAGE_SIZE + topOffset;
                peopleInARow = 0;
                positionFromLeft = startingPositionFromLeft;
                numberOfRows++;

            } else {
                peopleInARow += 1;
                positionFromLeft += IMAGE_SIZE + leftOffset;
            }



            [scroll addSubview:contactContainer];
            [scroll bringSubviewToFront:contactContainer];


        }

    }

    NSLog(@"%i", numberOfRows);

    scroll.contentSize = CGSizeMake(screenWidth, 150 * numberOfRows);
    scroll.pagingEnabled = NO;

    [self.view addSubview:scroll];
    [self.view bringSubviewToFront:scroll];


}

- (IBAction)userDeniedAccess:(id)sender {
    NSLog(@"Denied");
}

@end

有谁能告诉我重写这个的最佳方法以及我做错了什么标准/约定(可能在MVC中)?

2 个答案:

答案 0 :(得分:3)

任何事情你都没有违反MVC。视图控制器加载一些联系人并在视图中显示它们。由联系人表示的模型和视图根本没有耦合。从MVC的角度来看,这是正确的。

正如你所说,这是一个简单的应用程序。如果应用程序变得更大,更复杂,您可能需要为代码添加一些设计。但是这种设计对于这种复杂程度是有益的。例如,如果此类变得更大且更复杂,您可以将联系人加载部分分成新类。

然而,你的代码有一个非常糟糕的事情。方法userAllowedForAccess包含超过100行代码。必须在类级别以及方法和功能中维护模块化。将代码分离为多种方法,具体取决于它执行的功能。例如:

UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0,0, 320, 55)];
header.backgroundColor = [UIColor colorWithRed:34/255.0 green:34/255.0 blue:34/255.0 alpha:1];

[header.layer setShadowColor:[UIColor colorWithRed:14/255.0 green:14/255.0 blue:14/255.0 alpha:.5].CGColor];
[header.layer setShadowOpacity:0];
[header.layer setShadowRadius:3.0];
[header.layer setShadowOffset:CGSizeMake(2.0, 2.0)];

[self.view addSubview:header];
[self.view bringSubviewToFront:[self.view viewWithTag:100]];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration: .7];
[UIView setAnimationDelay: 0];


[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

可以在名为- (void) setupHeaderView的方法中提取,您可以使用另一种方法加载联系人- (NSArray *) getContacts或仅- (NSArray *) contacts以匹配Objective-C的getter定义样式。

答案 1 :(得分:2)

我会开始重构你的

- (IBAction)userAllowedForAccess

较小的原子方法中的方法。有一种基本上可以完成所有事情的方法通常是一个坏主意。