【问题标题】:Color picker quandary颜色选择器的困惑
【发布时间】:2014-06-12 05:15:11
【问题描述】:

我正在尝试实现一个简单的颜色选择器,该颜色选择器由UIImageView 中的图像组成。当用户在其上拖动手指时,我希望相邻视图使用当前像素颜色不断更新。

我在@rdelmar 对this question on SO 的回答中找到了接近理想解决方案的东西,因此我借用了代码并对其进行了修改,以将pickedColor 发送回AddCategoryViewController 上的方法。但是,此方法 (setColorview) 不会更新 colorView

我的断点和 NSLog 显示颜色信息正在从触摸中收集、发送和接收,但显然没有应用,正如受影响的 UIView colorView 不反映颜色的事实所示。最明显的问题是属性colorView 读取null,我不明白为什么。

作为奖励,我真的希望选择器能够响应滑动手指,而不仅仅是点击。

我已经在下面包含了所有相关代码,重要的行用//************************标记

感谢收看!感谢所有帮助!

代码从这里开始,文件用--------------------------分隔:

//
//  UIView+UIView_ColorOfPoint.m
//  WMDGx
//
//

#import "UIView+UIView_ColorOfPoint.h"
#import <QuartzCore/QuartzCore.h>


@implementation UIView (UIView_ColorOfPoint)

-(UIColor *) colorOfPoint:(CGPoint)point
{
    unsigned char pixel[4] = {0};
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pixel,
                                                 1, 1, 8, 4, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);

    CGContextTranslateCTM(context, -point.x, -point.y);

    [self.layer renderInContext:context];

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    UIColor *color = [UIColor colorWithRed:pixel[0]/255.0
                                     green:pixel[1]/255.0 blue:pixel[2]/255.0
                                     alpha:pixel[3]/255.0];
    return color;
}

@end




-----------------------------------------


//
//  ColorPickerView.m
//  WMDGx
//
//

#import "ColorPickerView.h"

AddCategoryViewController *addCatVC;

@implementation ColorPickerView


- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint loc = [touch locationInView:self];
    self.pickedColor = [self colorOfPoint:loc];
    NSLog(@"Touches began");

    //******************** For sending color info to setColorView in AddCategoryViewController
    addCatVC = [[AddCategoryViewController alloc]init];
    addCatVC.colorForColorView = self.pickedColor;

    NSLog(@"Picked color is %@",self.pickedColor);

    //******************** Call the method in AddCategoryViewController, which should display the color of the current pixel
    [addCatVC setColorview];
}


@end



--------------------------------


//
//  AddCategoryViewController.m
//  WMDGx
//
//

#import "AddCategoryViewController.h"

@interface AddCategoryViewController ()

@end

@implementation AddCategoryViewController

NSMutableArray *array;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Do any additional setup after loading the view.
    self.catTextField.delegate = self;
    [self.pickerImageView setUserInteractionEnabled:YES];

    self.colorView.layer.cornerRadius = 6;

    // ********************I put this NSLog here to check the status of the property self.colorView

    NSLog(@"Color view is %@",self.colorView);//_colorView  UIView * 0x8a63d30 0x08a63d30 (from Variables View)
}

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

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [self.catTextField resignFirstResponder];
    return YES;
}


-(void)setColorview // ********************This is where the backgroundColor of self.colorView should be set
{
    NSLog(@"colorForColorView is %@",self.colorForColorView);

    NSLog(@"Color view is %@",self.colorView); //_colorView UIView *    nil 0x00000000 (from Variables View)

    [self.colorView setBackgroundColor:self.colorForColorView]; //colorView should display the color, but doesn't

    NSLog(@"Color view is %@",self.colorView); //_colorView UIView *    nil 0x00000000 (from Variables View)

    NSLog(@"Color view color is %@",self.colorView.backgroundColor);
}

- (IBAction)saveButton:(UIBarButtonItem *)sender
{
    if (self.catTextField.text.length < 1)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No category created"
                                                        message:@"Please create a new category"
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
    }

    else if (!self.colorView.backgroundColor)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No color selected"
                                                        message:@"Please select a color for your new category"
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
    }
    else
    {
        NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
        self.thisCategory = [WMDGCategory MR_createInContext:localContext];
        self.thisCategory.name = [self.catTextField.text uppercaseString];
        self.thisCategory.color = self.colorView.backgroundColor;
        [localContext MR_saveToPersistentStoreAndWait];
        [self.thisCell setUserInteractionEnabled:NO];
        [self.delegate addCatControllerDidSave];
    }
}

- (IBAction)cancelButton:(UIBarButtonItem *)sender
{
    [self.delegate addCatControllerDidCancel:self.thisCategory];

}

@end

【问题讨论】:

    标签: ios objective-c color-picker


    【解决方案1】:

    这是我用于此目的的代码。除了开始触摸之外,我还有相同的触摸移动代码,并且允许您也想要的滑动效果。我的相邻视图有一个标签 200,我根据所选颜色查找并设置它。看起来你的链接代码比我的要干净一些,但也许看到这个会很有用。

    首先,当我接触到时:

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSSet *allTouches = [event allTouches];
    
        if ([allTouches count] != 1)
            return;
    
        UIView *picker = [self.view viewWithTag:100];
    
        UITouch *touch = [[allTouches allObjects] objectAtIndex:0];
        CGPoint p = [touch locationInView:self.view];
        if (CGRectContainsPoint(picker.frame, p))
        {
            printf("Hit gradient!\n");
            p = [touch locationInView:picker];
            UIColor *c = [self getPixelColor:[UIImage imageNamed:@"gradient.png"]
                                    xLoc:p.x
                                    yLoc:p.y];
    
            UIView *display = [self.view viewWithTag:200]; // representative color
            [display setBackgroundColor:c];
        }
    }
    

    获取颜色的代码(我相信这段代码是改编自 SO 上的其他代码):

    - (UIColor*)getPixelColor:(UIImage *)image xLoc:(int)x yLoc:(int)y
    {
        CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
        const UInt8* data = CFDataGetBytePtr(pixelData);
        if (x < 0 || x >= image.size.width || y < 0 || y >= image.size.height)
        {
            CFRelease(pixelData);
            return [UIColor whiteColor];
        }
        int pixelInfo = ((image.size.width  * y) + x ) * 4;
    
        UInt8 red = data[pixelInfo];
        UInt8 green = data[(pixelInfo + 1)];
        UInt8 blue = data[pixelInfo + 2];
        UInt8 alpha = data[pixelInfo + 3];
        CFRelease(pixelData);
    
        UIColor* color = [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha/255.0f];
    
        return color;
    }
    

    【讨论】:

    • 酷!两个问题:1)你把这两块代码放在哪里? 2)这是否消除了对我包含在我的 UIView 类别的需求?
    • 我有一个 ColorPicker UIViewController,这段代码在 ColorPicker 类中。这确实消除了对类别的需求,因为我直接查询我正在使用的图像,而不是渲染视图然后查询该像素。 (再看代码有点搞笑,因为我没有从UIImageView中抓取图片,我直接从文件中查询。理论上你可以直接在UIImageView(picker)中查询图片,但是我没有'没有测试这个。)
    • 谢谢!我会在早上试一试,让你知道会发生什么。我仍然对那个空视图感到困惑。使用标签时结果相同。
    • 完美运行,@Nathan!我很感激。一个挥之不去的问题是,由于您查询的是图像而不是视图,并且由于我使用的是 2x 图像,因此事情完全不相关。目前,我切换到图像的 1x 版本,一切都很好。但是,对于最终版本,我需要协调这件事,可能是通过弄清楚如何查询视图。我很高兴给你一张绿色支票和赞成票,但我很高兴听到这方面的任何指导。谢谢,朋友!
    • 我还没有得到我正在使用的应用程序,我正在使用 2x 图像,所以我没有经过测试的答案。但是,您可以查看 UIImage 的 scale 属性以查看图像是否为 2x。然后您应该能够将触摸的偏移量缩放 2 倍。
    猜你喜欢
    • 2011-09-04
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    相关资源
    最近更新 更多