颜色选择器的困惑
Posted
技术标签:
【中文标题】颜色选择器的困惑【英文标题】: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
【问题讨论】:
【参考方案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 倍。以上是关于颜色选择器的困惑的主要内容,如果未能解决你的问题,请参考以下文章