iOS slider to change a color changes wrong label - uilabel

Am using Xcode 4.5, targeting iOS5 and above.
I am updating an app, using Storyboard for all scenes. Have a previous XIB and controller that I converted, but it is not functioning the same way.
The controller allows changing the color of text and creating new colors.
Creating new RGB colors relies on 3 Horizontal Sliders to change a swatch of color and the corresponding RGB values on 3 separate labels, before saving the new color. The sliders are Value Changed Sent Events and are hooked up to one action.
The issue: when I change any of the sliders, ONLY the red label and red color value.
I've tried changing the individual cases for the sliders into separate actions, and moving the setPreviewImage into a method of its own, but then, it does not change the swatch.
Any help would be greatly appreciated. Thanks in advance.
-(IBAction)RGBSliderChange:(UISlider *)sender {
switch ([sender tag])
{
case 0: {
self.rLabel.text = [NSString stringWithFormat:#"%d", (int)[sender value]];
break;
}
case 1: {
self.gLabel.text = [NSString stringWithFormat:#"%d", (int)[sender value]];
break;
}
case 2: {
self.bLabel.text = [NSString stringWithFormat:#"%d", (int)[sender value]];
break;
}
default:
break;
}
self.colorPreviewImage.backgroundColor = [UIColor colorWithRed:(CGFloat)[self.rLabel.text floatValue]/256
green:(CGFloat)[self.gLabel.text floatValue]/256
blue:(CGFloat)[self.bLabel.text floatValue]/256
alpha:1.0];
}

I have solved this issue. It turns out that I did not have the tag set for each slider and label. They were all set to 0, hence any change only affected the Red color label.
Setting each slider and label to a different tag solved the problem!
Cheers!

Related

NSVisualEffectView change takes more than one click to change

So I have an NSVisualEffectView hooked up with a button and some icons. The material of this view is originally equal to NSVisualEffectMaterialDark in other words, Vibrant Dark.
The following code I wrote is supposed to do the following:
1) Detect if the view's material is NSVisualEffectMaterialDark or NSVisualEffectMaterialLight
2) Change the BOOL isDark to YES/NO respectively
3) Change the view's appearance, in other words the material, from Dark to Light / Light to Dark based on the current view.
The problem is that when I run the app and click the button, NSVisualEffectView's colour changes from a saturated dark to a less one, and not Light as it is supposed to.
What can I do to fix this problem and prevent it from happening?
Note: the NSVisualEffectView's name is sideBar, the button's name is lightButton and isDark is originally set to YES.
Here is my code:
-(IBAction)toggleLighting:(id)sender{
if (self.sideBar.material == NSVisualEffectMaterialDark){
_lightButton.title = (#"Dark Mode");
[_lightButton setImage:[NSImage imageNamed:#"Dark Mode Icon"]];
[_lightButton setAlternateImage:[NSImage imageNamed:#"Dark Mode Icon (Alt)"]];
isDark = YES;
NSLog(#"Changed to Light Theme");
} else if (self.sideBar.material == NSVisualEffectMaterialLight){
_lightButton.title = (#"Light Mode");
[_lightButton setImage:[NSImage imageNamed:#"Light Mode Icon"]];
[_lightButton setAlternateImage:[NSImage imageNamed:#"Light Mode Icon (Alt)"]];
isDark = NO;
NSLog(#"Changed to Dark Theme");
}
if (isDark==YES){
_sideBar.material = NSVisualEffectMaterialLight;
isDark = NO;
} else if (isDark==NO) {
_sideBar.material = NSVisualEffectMaterialDark;
isDark = YES;
}
}
It turns out that the code I wrote is a little problematic, as expected of course.
The NSVisualEffectView has none of the above material it checks for, NSVisualEffectMaterialDark nor NSVisualEffectMaterialLight, therefore both conditions are false. It seems that it chooses to set the material to a different type of dark so that the materials will finally match and be able to compare them properly.
By stating either material (NSVisualEffectMaterialDark nor NSVisualEffectMaterialLight), in - (void)applicationDidFinishLaunching:(NSNotification *)aNotification I was able to fix the issue where I had to click twice for the button to actually work.
EDIT:
It turns out there are other materials I wasn't aware of and they happened to be the desired ones.These are NSVisualEffectMaterialMediumLight and NSVisualEffectMaterialUltraDark.

Resize MKMapView

Looks like simple task. But when I try to resize using setFrame method I got glitches. There are some other UIViews resized using setFrame method and it works perfectly. I made custom application with slider bar and map view. SlideBar changes X position for MKMapView, but keeps width equals to screen width. This approach works fine for all Views. But MKMapView resizes with smooth troubles. Can anyone please give a clue why it's happening and how to solve it?
I had the same problem, which seems to occur only on iOS 6 (Apple Maps) and not on iOS 5 (Google Maps).
My solution was to take a "screenshot" of the map when the user start dragging the divider handle, replace the map with this screenshot during the drag, and put the map back when the finger is released.
I used the code from How to capture UIView to UIImage without loss of quality on retina display for UIView screenshot and Nikolai Ruhe's answer at How do I release a CGImageRef in iOS for a nice background color.
My UIPanGestureRecognizer action is something like this (the (MKMapView)self.map is a subview of (UIView)self.mapContainer with autoresizing set on Interface Builder):
- (IBAction)handleMapPullup:(UIPanGestureRecognizer *)sender
{
CGPoint translation = [sender translationInView:self.mapContainer];
// save current map center
static CLLocationCoordinate2D centerCoordinate;
switch (sender.state) {
case UIGestureRecognizerStateBegan: {
// Save map center coordinate
centerCoordinate = self.map.centerCoordinate;
// Take a "screenshot" of the map and set the size adjustments
UIImage *mapScreenshot = [UIImage imageWithView:self.map];
self.mapImage = [[UIImageView alloc] initWithImage:mapScreenshot];
self.mapImage.autoresizingMask = self.map.autoresizingMask;
self.mapImage.contentMode = UIViewContentModeCenter;
self.mapImage.clipsToBounds = YES;
self.mapImage.backgroundColor = [mapScreenshot mergedColor];
// Replace the map with a screenshot
[self.map removeFromSuperview];
[self.mapContainer insertSubview:self.mapImage atIndex:0];
} break;
case UIGestureRecognizerStateChanged:
break;
default:
// Resize the map to the new dimension
self.map.frame = self.mapImage.frame;
// Replace the screenshot with the resized map
[self.mapImage removeFromSuperview];
[self.mapContainer insertSubview:self.map atIndex:0];
// Empty screenshot memory
self.mapImage = nil;
break;
}
// resize map container according do the translation value
CGRect mapFrame = self.mapContainer.frame;
mapFrame.size.height += translation.y;
// reset translation to make a relative read on next event
[sender setTranslation:CGPointZero inView:self.mapContainer];
self.mapContainer.frame = mapFrame;
self.map.centerCoordinate = centerCoordinate; // keep center
}

NSTableView Cell Display Issue

I'm using a view-based NSTableView, and I've ran across a little issue.
I'm trying to switch the text color of my two labels from black to white when highlighted.
To do so, I've written the following code,
- (void)tableViewSelectionDidChange:(NSNotification *)notification
{
NSView * viewInQuestion = [table viewAtColumn:0 row:[table selectedRow] makeIfNecessary:YES];
if ([viewInQuestion isNotEqualTo:lastViewSelected])
{
[(NSTextField*)lastViewSelected.subviews.lastObject setTextColor:NSColor.blackColor];
[(NSTextField*)[lastViewSelected.subviews objectAtIndex:1] setTextColor:NSColor.grayColor];
}
[(NSTextField*)viewInQuestion.subviews.lastObject setTextColor:NSColor.whiteColor];
[(NSTextField*)[viewInQuestion.subviews objectAtIndex:1] setTextColor:NSColor.whiteColor];
lastViewSelected = viewInQuestion;
}
That works great; I get this result:
The issue is that sometimes the text doesn't appear white even though an NSLog told me that the NSTextField's color was NSCalibratedWhite (or whatever it's called).
The color also switches back to black when the textField is not visible (scrolling away from it and then back). Yet again, even when it does this, the NSTextField's color is still logged as white.
Overriding setBackgroundStyle on NSTableViewCell has worked perfectly for me, at least on OS X 10.8. (Given the number of relevant questions here on SO, one can guess that there used to be some problems before.)
The background style is updated on selection events and on window activation/deactivation, just as one would expect.
Here's my custom cell impl — as trivial as it can get:
#implementation RuntimeInstanceCellView
- (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle {
[super setBackgroundStyle:backgroundStyle];
self.detailTextField.textColor = (backgroundStyle == NSBackgroundStyleLight ? [NSColor darkGrayColor] : [NSColor colorWithCalibratedWhite:0.85 alpha:1.0]);
// self.detailTextField.textColor = (backgroundStyle == NSBackgroundStyleLight ? [NSColor blackColor] : [NSColor whiteColor]);
}
#end
My method is very hacky, and probably not the optimal solution; But it resolves it so that's good.
Assuming you implemented tableSelectionDidChange the way I have, all you need to do is register an NSNotification and implement a custom method that should be more explicit.
In the init, awake, or didFinishLaunching part of your application...
NSView * contentView = table.enclosingScrollView.contentView;
[contentView setPostsFrameChangedNotifications:YES];
[NSNotificationCenter.defaultCenter addObserver:self selector:#selector(boundsDidChange:) name:NSViewBoundsDidChangeNotification object:contentView];
Somewhere else in the program...
(assuming hasUpdatedCell is a BOOLEAN property)
- (void)boundsDidChange:(NSNotification *)notification
{
/* Bounds can change while nothing is selected--> but we only want to execute the method if a cell is selected. */
if ([table selectedRow] == -1) {return;}
NSRect visibleRect = table.enclosingScrollView.visibleRect;
NSView * viewInQuestion = [table viewAtColumn:0 row:[table selectedRow] makeIfNecessary:YES];
NSPoint selectedViewOrigin = [viewInQuestion convertPoint:viewInQuestion.frame.origin toView:table.enclosingScrollView];
/* If the selected cell is visible, then we can go ahead and redraw the white text as a part of the workaround.
This is because scrolling away from the selected cell and back will make the cell revert back to black. */
BOOL cellVisible = NSPointInRect(selectedViewOrigin, visibleRect);
/* We already know we need to update it, and we will so we don't need to evaluate the next step in the program */
if (!cellVisible && !hasUpdatedCell) {return;}
if (cellVisible && !hasUpdatedCell)
{
/* The cell is visible but we haven't updated. Let's do it then. */
[self tableViewSelectionDidChange:nil];
hasUpdatedCell = YES;
}
else if (!cellVisible)
{
/* The cell is not visible and we need to update next time. */
hasUpdatedCell = NO;
}
}
Things then should get displayed properly.

Change font color of UITextView

I have a UITextView where the user can input text. Say the user has already inputted a value. How can I change the font color of that already typed text and future typed text to a different one with the click of a button?
I already have it set up where I can change the color of the text but it only works if I choose a color BEFORE I start typing. After I start typing and I attempt to change the color, it doesn't do anything.
I have this:
-(IBAction)changeInkColor:(id)sender
{
[inkTextField setTextColor:[UIColor greenColor]];
inkTextField.text=#"text";
}
and that actually works and displays "text" in green only if there is no text already in the view. However if I type something in and then hit this button, nothing happens.
I just tried that and I had no problems. I set up a button that called [myTextView setTextColor:[UIColor redColor]];
After typing a bit with black text color, I pressed the button, and everything turned red. Then I continued typing, all in red.
Are you using setTextColor: to do this also?
In the end, setTextColor: is the answer, there's an important detail missing from the earlier answers: To get this to work in iOS 8, I had to set the color =after= I set the text.
Hence,
- (void)viewDidLoad
{
[super viewDidLoad];
_myTextView.textColor = [UIColor whiteColor];
_myTextView.text = #"yadda yadda yadda...";
// etc., snip
Did NOT work, while
- (void)viewDidLoad
{
[super viewDidLoad];
_myTextView.text = #"yadda yadda yadda...";
_myTextView.textColor = [UIColor whiteColor];
// etc., snip
DID work. This strikes me as a bug in iOS 8, which I will write up.
You can fix this (at least in Xcode 8.2) in IB by toggling the textColor button (6th button in the row). With this button selected, if you set the textColor programmatically before you enter text in the view, the color will "stick." I have not found an elegant way to set this on the text view programatically.
However you can also work around this in code:
textView.text = #" ";
textView.textColor = UIColor.redColor;
textView.text = #"";
I had the same problem as you, then I realised that the text was not changing colour, and was red by default because I was doing:
placeholder = #"Welcome";
instead of
WelcomeField.text = #"Welcome";
Hope it helps
use attributed text of UITextField
NSAttributedString *string = [[NSAttributedString alloc]initWithString:self.textField.text attributes:#{NSForegroundColorAttributeName:color}];
self.textField.attributedText = string;
Very interestingly, while
[_nameLabel setTextColor: [UIColor redColor]];
didn't work,
_nameLabel.textColor = [UIColor redColor]];
worked. Hope it helps for others. Cheers.

How to toggle autocorrectionType on and off for an existing UITextView

I have a UITextView in my iPhone app for which I want to be able to toggle the autocorrectionType.
When a user is editing the text view, I want the autocorrectionType to be set to UIAutocorrectionTypeYes.
When the text view is not being edited, I want the autocorrectionType to be set to UIAutocorrectionTypeNo (because I don't want any of the red-dotted underlines generated by autocorrection to be visible)
Simply toggling the autocorrectionType like this:
myTextView.autocorrectionType = UITextAutocorrectionTypeYes;
myTextView.autocorrectionType = UITextAutocorrectionTypeNo;
Doesn't seem to work.
Are there limitations on when I can toggle the autocorrectionType or in which situations the changed autocorrectionType takes effect?
EDIT:
To clarify:
There are no issues setting the autocorrectionType when initializing the UITextView. The problem arises when I want to change the autocorrectionType for an existing UITextView. In my case I want to give users the advantage of autocorrection when they edit a UITextView, but don't want any spelling errors pointed out with the red-dotted underlines when the UITextView is not being edited - in part because I am also exporting a UIView containing the UITextView as an image.
The problem is that just changing the value of my UITextView's autocorrectionType property doesn't work.
Here's an easy way to do this for the image export scenario :
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
// Turn spell check on
textView.autocorrectionType = UITextAutocorrectionTypeYes;
return YES;
}
- (BOOL)textViewShouldEndEditing:(UITextView *)textView
{
// Turn spell check off and clean up red squiggles.
textView.autocorrectionType = UITextAutocorrectionTypeNo;
NSString *currentText = textView.text;
textView.text = #"";
textView.text = currentText;
return YES;
}
You can try to first hide the keyboard first and then displaying it again. Also update the uitextview. If [UITextView setNeedsDisplay] doesn't work for you, try [UITextView insertText:] and then [UITextView deleteBackward]
[textView resignFirstResponde];
textView.autocorrectionType = UITextAutocorrectionTypeNo;
[textView becomeFirstResponder];
[textView setNeedsDisplay];
or
[textView insertText:#" "];
[textView deleteBackward];
In addition to changing the autocorrection type to UITextAutoCorrectionNo, the UITextView must be forced to reevaluate its correction state. setNeedsRedraw is insufficient but setting the text to itself, e.g.
textView.autocorrectionType = UITextAutocorrectionTypeNo;
textView.text = textView.text;
makes the red dashed lines go away. NOTE: this workaround relies on undocumented behavior and is not guaranteed to work on future iOS releases.
Try calling -setNeedsDisplay on the text view after you've changed the autocorrectionType. This will force the text view to redraw and will hopefully clear the red underlines.
myTextView.autocorrectionType = UITextAutocorrectionTypeNo;
[myTextView setNeedsDisplay];
func activateTextViewAutocorrection() {
textView.autocorrectionType = .default
textView.reloadInputViews()
}
func deactivateTextViewAutocorrection() {
textView.autocorrectionType = .no
textView.reloadInputViews()
}