在IOS的背景下,MVC甚至意味着什么?

时间:2016-03-21 10:34:58

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

我曾经有一个庞大的8k +行FeedViewController,任何时候我想改变任何涉及状态外观的东西我必须改变不少于十几个viewcontrllers所以我决定尝试重构遵循MVC类型标准。我将大部分功能放在tableviewcells中,这样我就可以更改单元类而不是12个文件,现在我已经听到了#34;你应该保持你的VIEWS笨......这真的是错的吗?

//
//  TriCornerFeedCell.m

//

//
#import "NSDate+TimeAgo.h"
#import "TriCornerFeedCell.h"
#import "AFNetworking.h"


@implementation TriCornerFeedCell

-(void)refreshGestureRecognizers{

    while (self.gestureRecognizers.count) {
        [self removeGestureRecognizer:[self.gestureRecognizers objectAtIndex:0]];
    }
    UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(processDoubleTap:)];
    doubleTap.numberOfTapsRequired = 2;
    [self addGestureRecognizer:doubleTap];

    UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
                                          initWithTarget:self action:@selector(handleLongPress:)];
    lpgr.minimumPressDuration = 1.3; //seconds
    lpgr.delegate = self;
    [self addGestureRecognizer:lpgr];
}




-(void)refreshCell{

     _sdmanager = [SDWebImageManager sharedManager];


//Set Name Label
    self.NameLabel.text=[NSString stringWithFormat:@"%@ %@",self.statusObject.first_name,self.statusObject.last_name];

//Set Message Label
    if(self.statusObject.message!=nil){
        self.StatusLabel.enabledTextCheckingTypes = NSTextCheckingTypeLink;
        self.StatusLabel.text = self.statusObject.message;
        self.StatusLabel.delegate = self;
        [self checkForShoutoutsAndHashtags];
        self.StatusLabel.lineBreakMode=0;
        self.StatusLabel.numberOfLines=0;
        //Cell.StatusLabel.text=[tempDictionary objectForKey:@"message"];
        [self.StatusLabel sizeToFit];

    }

//Set Date Label
    NSDate *date = [[NSDate alloc] initWithTimeIntervalSince1970:self.statusObject.created];
    self.timeLabel.text=[date timeAgo];

//Set Bump Views
    if(self.statusObject.isBumped){
         [self.bumpCornerBG setBackgroundImage:[UIImage imageNamed:@"corner_bump_yellow.png"] forState:UIControlStateNormal];

    }else{
        [self.bumpCornerBG setBackgroundImage:[UIImage imageNamed:@"corner_bump_grey.png"] forState:UIControlStateNormal];
    }

    self.bumpCount.text=[@(self.statusObject.bump_count) stringValue];
    [self.bumpClearViewBtn addTarget:self action:@selector(bump:) forControlEvents:UIControlEventTouchUpInside];
    [self.bumpCornerBG addTarget:self action:@selector(bump:) forControlEvents:UIControlEventTouchUpInside];


//Set Comment Related Views


    if(self.statusObject.comment_count>0){
        NSLog(@"COMMENT_COUNT:%d",self.statusObject.comment_count);
        [self.commentCount setHidden:NO];
        [self.miniCommentColorCircle setHidden:NO];
        self.commentCount.text=[@(self.statusObject.comment_count) stringValue];
    }else{
        [self.commentCount setHidden:YES];
        [self.miniCommentColorCircle setHidden:YES];
    }

//Set Follow Btn Views
    [self.followBtn.titleLabel setFont:[UIFont fontWithName:@"BloggerSans" size:14]];
    [self.followBtn removeFromSuperview];
    if(!self.statusObject.isFollowing){

        [self.followBtn removeFromSuperview];
        UIButton *followBtn= [[UIButton alloc] initWithFrame:CGRectMake(235, 16, 75, 25)];
        [followBtn setImage:nil forState:UIControlStateNormal];
        followBtn.layer.cornerRadius =2; // this value vary as per your desire
        [followBtn.titleLabel setFont:[UIFont fontWithName:@"BloggerSans" size:14.0f]];
        followBtn.titleEdgeInsets = UIEdgeInsetsMake(3, 0, 0, 0);
        followBtn.clipsToBounds = YES;
        [followBtn setTitleColor:[self colorWithHexString:@"ff68a8"] forState:UIControlStateNormal];
        followBtn.layer.borderWidth=1.5f;
        followBtn.layer.borderColor=[[self colorWithHexString:@"ff68a8"] CGColor];
        [followBtn setTitle:@"Follow" forState:UIControlStateNormal];
        [followBtn addTarget:self action:@selector(follow) forControlEvents:UIControlEventTouchUpInside];
        self.followBtn=followBtn;
        [self addSubview:self.followBtn];

    }


//Reset icon to default in case default==nill
    [self bringSubviewToFront:self.DefaultImgBorder];
    [self bringSubviewToFront:self.DefaultImgBtn];
    UIImage *noDefault = [UIImage imageNamed:@"female_mini_no_default_icon.png"];
    [self.DefaultImgBtn setBackgroundImage:noDefault forState:UIControlStateNormal];

//Attempt to create hexagon cropped default photo
    UIImage *hex_img = [UIImage imageNamed:@"big_hex_thumb.png"];
    UIImage *tan=[UIImage imageNamed:@"feed_grey.png"];
    UIImage *finalBG= [self maskImage:tan withMask:hex_img];
    [self.DefaultImgBorder setImage:finalBG];
    NSURL *thumb_url=[NSURL URLWithString:[NSString stringWithFormat:@"%@%@",s3thumbURL,self.statusObject.thumb_img]];
    @autoreleasepool {
        [_sdmanager downloadWithURL:thumb_url
                            options:0
                           progress:^(NSInteger receivedSize, NSInteger expectedSize){}completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished){
             if (image)
             {
                 UIImage *thumbimg = image;
                 UIImage *hex_img = [UIImage imageNamed:@"big_hex_thumb.png"];
                 UIImage *noDefault = [UIImage imageNamed:@"female_mini_no_default_icon.png"];
                 [self.DefaultImgBtn setBackgroundImage:noDefault forState:UIControlStateNormal];

                 UIImage *finalImg= [self maskImage:thumbimg withMask:hex_img];
                 [self.DefaultImgBtn setBackgroundImage:finalImg forState:UIControlStateNormal ];
             }
         }];
    }
    [self.DefaultImgBtn removeTarget:nil
                              action:NULL
                    forControlEvents:UIControlEventAllEvents];
    [self.DefaultImgBtn addTarget:self action:@selector(viewProfile:) forControlEvents:UIControlEventTouchUpInside];


//Misc Stuff
    [self setSelectionStyle:UITableViewCellSelectionStyleNone];

}

#pragma mark - Interaction Methods

-(void)follow{


    [self.followSpinner removeFromSuperview];
    [self.followBtn removeFromSuperview];
    self.followSpinner = [[RTSpinKitView alloc] initWithStyle:RTSpinKitViewStyleFadingCircleAlt color: [self colorWithHexString:@"b4b4b2"] spinnerSize:25];
    [self.followSpinner setFrame:CGRectMake(260,15,30,30)];
    self.spinner.tag=9;
    [self addSubview:self.followSpinner];
    [self.statusObject follow];
}
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{

    if (self.indexPath != nil && gestureRecognizer.state == UIGestureRecognizerStateBegan) {


        NSString*loggedin_uid = [[NSUserDefaults standardUserDefaults] objectForKey:@"uid"];


        if([self.statusObject.IMPORT_SOURCE isEqualToString:@"INSTAGRAM"] || [self.statusObject.IMPORT_SOURCE isEqualToString:@"TWITTER"]){

            if([loggedin_uid isEqualToString:@"1"] || [loggedin_uid isEqualToString:@"2"]){

                [self.delegate showImportAdminControls:self.indexPath];
            }

        }else{

            if([loggedin_uid isEqualToString:@"1"] || [loggedin_uid isEqualToString:@"2"]){

                [self.delegate showAdminControls:self.indexPath];

            }else if ([self.statusObject.uid isEqualToString:loggedin_uid]){

                [self.delegate deletePostAlert:self.indexPath];

            }
        }

    }
}
- (void) processDoubleTap:(UITapGestureRecognizer *)sender
{


    if (sender.state == UIGestureRecognizerStateEnded)
    {
        if (self.indexPath)
        {
            self.statusObject.indexPath=self.indexPath;

            if(!self.statusObject.isBumped){


                int value = self.statusObject.bump_count+1;
                self.statusObject.isBumped=YES;
                self.statusObject.bump_count=value;
                [self.bumpCount setText:[@(value) stringValue]];
                [self.bumpCornerBG setBackgroundImage:[UIImage imageNamed:@"corner_bump_yellow.png"] forState:UIControlStateNormal];
                UIImageView *bumpBlowUpIcon=[[UIImageView alloc]initWithFrame:CGRectMake((self.frame.size.width/2)-5, (self.frame.size.height/2)-5, 10, 10)];
                [bumpBlowUpIcon setImage:[UIImage imageNamed:@"heart_yellow.png"]];
                bumpBlowUpIcon.alpha=.2;
                [self addSubview:bumpBlowUpIcon];

                [UIView animateWithDuration:.8 delay:0 usingSpringWithDamping:.3 initialSpringVelocity:.3 options:UIViewAnimationOptionCurveEaseOut animations:^{

                    [bumpBlowUpIcon setFrame:CGRectMake((self.frame.size.width/2)-(self.frame.size.height/2), 0, self.frame.size.height, self.frame.size.height)];
                    bumpBlowUpIcon.alpha=.5;

                }completion:^(BOOL finished) {

                    [bumpBlowUpIcon removeFromSuperview];
                }];


            }else{

                int value = self.statusObject.bump_count-1;
                self.statusObject.isBumped=NO;
                self.statusObject.bump_count=value;
                [self.bumpCount setText:[@(value) stringValue]];
                [self.bumpCornerBG setBackgroundImage:[UIImage imageNamed:@"corner_bump_grey.png"] forState:UIControlStateNormal];
            }



            [self.statusObject bump];





        }
    }

}




-(void)viewProfile{



}

-(void)viewHashtag{



}



#pragma mark - Misc Methods




- (UIImage*) maskImage:(UIImage *) image withMask:(UIImage *) mask
{
    CGImageRef imageReference = image.CGImage;
    CGImageRef maskReference = mask.CGImage;

    CGImageRef imageMask = CGImageMaskCreate(CGImageGetWidth(maskReference),
                                             CGImageGetHeight(maskReference),
                                             CGImageGetBitsPerComponent(maskReference),
                                             CGImageGetBitsPerPixel(maskReference),
                                             CGImageGetBytesPerRow(maskReference),
                                             CGImageGetDataProvider(maskReference),
                                             NULL, // Decode is null
                                             YES // Should interpolate
                                             );

    CGImageRef maskedReference = CGImageCreateWithMask(imageReference, imageMask);
    CGImageRelease(imageMask);

    UIImage *maskedImage = [UIImage imageWithCGImage:maskedReference];
    CGImageRelease(maskedReference);

    return maskedImage;
}

-(UIColor*)colorWithHexString:(NSString*)hex
{
    NSString *cString = [[hex stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];

    // String should be 6 or 8 characters
    if ([cString length] < 6) return [UIColor grayColor];

    // strip 0X if it appears
    if ([cString hasPrefix:@"0X"]) cString = [cString substringFromIndex:2];

    if ([cString length] != 6) return  [UIColor grayColor];

    // Separate into r, g, b substrings
    NSRange range;
    range.location = 0;
    range.length = 2;
    NSString *rString = [cString substringWithRange:range];

    range.location = 2;
    NSString *gString = [cString substringWithRange:range];

    range.location = 4;
    NSString *bString = [cString substringWithRange:range];

    // Scan values
    unsigned int r, g, b;
    [[NSScanner scannerWithString:rString] scanHexInt:&r];
    [[NSScanner scannerWithString:gString] scanHexInt:&g];
    [[NSScanner scannerWithString:bString] scanHexInt:&b];

    return [UIColor colorWithRed:((float) r / 255.0f)
                           green:((float) g / 255.0f)
                            blue:((float) b / 255.0f)
                           alpha:1.0f];
}

@end

1 个答案:

答案 0 :(得分:0)

确定。我试图将所有评论合并到一个合适的答案中。

当你想坚持MVC模式时,你应该尽可能地保持你的观点愚蠢(关于视图和业务相关组件的耦合)。在最好的情况下,它们不应包含任何业务逻辑。 这意味着他们也不应该对业务对象(模型)有所了解。只要statusObject中的self.StatusLabel.text = self.statusObject.message;不是数据传输对象,让细胞自己检索它们的值就不是一个好主意 - 因为这些细胞需要知道你的模型结构。

通常每个视图都有自己的视图控制器,但是 - 当然 - 您可以使用所需的功能组合视图控制器。

例如:如果某些视图控制器需要数据,您可以引入一个单独的(与视图相关的)组件,该组件将提供该数据(例如,通过创建和返回单元格)。该组件将与您的模型数据(或数据传输对象)一起提供,并返回一个可供需要这些信息的所有视图控制器使用的结构。