I want to create a custom UISwtich with three positions. Is it possible?
You should be using UISegmentedControlif you want a standard UI-Element or configure a UISlider with a range of 2:
slider.minimumValue = 0;
slider.maximumValue = 2;
slider.continuous = NO;
And then set the minimumValueImage, maximumTrackImage and thumbImage to use appropriate images.
Not using the built-in UISwitch. You'll need to roll your own.
Why not use a UISegmentedControl?
Using UISlider is a good approach. But you would additionally want to adjust the mechanics of your UISlider to be more UISwitch-like. I.e., when you change its position incompletely then it should bounce back to the home position.
Here's what I ended up doing (using a part of FelixLam's answer):
UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(screenRect.size.width*0.5-width/2, screenRect.size.height*0.95-height, width, height)];
slider.minimumValue = 0;
slider.maximumValue = 2;
slider.continuous = NO;
slider.value = 1;
[slider addTarget:self action:#selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
Along with...
- (void)sliderAction:(UISlider *)slider {
float origValue = slider.value;
[UIView beginAnimations:nil context:NULL];
if (slider.value<1.9 && slider.value>0.1) slider.value=1;
else if (slider.value>1.9) slider.value=2;
else slider.value=0;
[UIView setAnimationDuration:0.2*fabs(slider.value-origValue)];
[UIView commitAnimations];
}
Related
I'm having a problem here with designing my UI in Xcode.
I've programmatically created(when a button is pressed) a UIImageView(black, transparent overlay), UITextView(editable), and a UIButton to clear these former two UISubviews.
This problem is all appearing both on the Simulator, and my iPhone.
This is my code
- (IBAction)openCommentTextView:(id)sender {
doneButton = [[UIButton alloc] initWithFrame:CGRectMake(20, 40, 60, 35)];
doneButton.alpha = 0.0;
doneButton.layer.cornerRadius = 7;
doneButton.layer.borderColor = [[UIColor colorWithWhite:1.0 alpha:1.0] CGColor];
doneButton.layer.borderWidth = 3;
[doneButton setTitle:#"Done" forState:UIControlStateNormal];
[doneButton setTitleColor:[UIColor colorWithWhite:1.0 alpha:1.0] forState:UIControlStateNormal];
doneButton.titleLabel.font = [UIFont fontWithName:#"AvenirNext-Regular" size:15];
[doneButton addTarget:self action:#selector(finishEditing:) forControlEvents:UIControlEventTouchUpInside];
commentTextView = [[UITextView alloc] initWithFrame:CGRectMake(20, 90, 280, 230)];
[commentTextView becomeFirstResponder];
commentTextView.alpha = 0.0;
if ([commentsTextViewViewer.text isEqual: #"Comment..."]) {
commentsTextViewViewer.text = #"";
} else {
commentTextView.text = commentsTextViewViewer.text;
}
commentTextView.keyboardAppearance = UIKeyboardAppearanceDark;
commentTextView.layer.cornerRadius = 7;
commentTextView.font = [UIFont fontWithName:#"GillSans" size:20];
commentTextView.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.4];
backgroundOverlay = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 330, 568)];
backgroundOverlay.backgroundColor = [UIColor colorWithWhite:0.0 alpha:1.0];
backgroundOverlay.alpha = 0.0;
[self.view insertSubview:doneButton atIndex:11];
[self.view insertSubview:commentTextView atIndex:10];
[self.view insertSubview:backgroundOverlay atIndex:9];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
commentTextView.alpha = 1.0;
doneButton.alpha = 1.0;
[UIView commitAnimations];
[UIView setAnimationDuration:0.3];
backgroundOverlay.alpha = 1.0;
[UIView commitAnimations];
}
However, somehow the UIButton(doneButton) and the UITextView(commentTextView) is under the UIImageView(black overlay). Both the UIButton and the UITextView responds. (I set the UIImageView(black overlay) alpha to 1.0, and the UIButton and UITextView didn't appear, although both responded)
It turned out like this (sorry I couldn't include the image directly into here... I didn't have enough reputation)
But when I copied this code and pasted into a new single-view application, it worked perfectly as I wished it to. (like this)
I really have no idea why this is happening... I've searched all over the web but with no success.
Is this something to do with XCode, or my iPhone itself?
I'd be very happy if someone can help me work this out.
Thank you.
A couple of things that might help. I've never had much luck in terms of the atIndex: method of view insertion except index 0. Try using relative position, since you know the button and textview NEED to be above the background overlay.
[self.view addSubview:backgroundOverlay];
[self.view insertSubview:doneButton aboveSubview:backgroundOverlay];
[self.view insertSubview:commentTextView aboveSubview:backgroundOverlay];
Also, you'll need a second call to [UIView beginAnimations:nil context:nil]; before animating the second bit of code. Or, alternatively, use the UIView animation blocks which is recommended if you're targeting iOS 4 or higher.
I've programmatically created a UISlider in viewDidLoad using the following code and when a button is pressed I want to hide the object and maybe use it again. I can't seem to get it to work. I've tried a number of approaches which all build correctly but none of which have the desired effect.
CGRect frame1 = CGRectMake(-5.0, 290.0, 100.0, 10.0);
UISlider *sliderSaveurFloral = [[UISlider alloc] initWithFrame:frame1];
[sliderSaveurFloral addTarget:self action:#selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
[sliderSaveurFloral setBackgroundColor:[UIColor clearColor]];
sliderSaveurFloral.minimumValue = 0.0;
sliderSaveurFloral.maximumValue = 50.0;
sliderSaveurFloral.continuous = YES;
sliderSaveurFloral.value = 0.0;
[self.view addSubview:sliderSaveurFloral];
CGAffineTransform trans2 = CGAffineTransformMakeRotation(M_PI * -0.5);
sliderSaveurFloral.transform = trans2;
[sliderSaveurFloral setValue:0];
UISlider inherits from UIView. I believe you can set the hidden property to make it invisible.
sliderSaveurFloral.hidden = YES; //Set it back to NO when you want it appear again
You may also have to make it not interactive when hidden,
sliderSaveurFloral.userInteractionEnabled = NO; //Set it back to YES later when you need
I find at least 5 other "UIView animation doesn't work" questions, I hate to add yet another one. :(. I'm sure this isn't something specific to alpha. Same issue with backgroundColor. So it is something basic.
This works:
[self.view viewWithTag:kPlayView].alpha = 0.75;
[self.view viewWithTag:kCancelView].alpha = 0.75;
[self.view viewWithTag:kTapViewTag].backgroundColor = [UIColor whiteColor];
This doesn't (it doesn't do anything):
//kPlayView and kCancelView are subviews of kTapViewTag
[UIView animateWithDuration:2.0 animations:^{
[self.view viewWithTag:kPlayView].alpha = 0.75;
[self.view viewWithTag:kCancelView].alpha = 0.75;
[self.view viewWithTag:kTapViewTag].backgroundColor = [UIColor whiteColor];
} ];
Why? This is called in the gesture handler for the kTapViewTag view. It is view with backgorundColor = [UIColor clearColor] that I want to fade to white and change alpha of subviews to 0.75 in response to tap gesture.
UPDATE:
The reverse works. This works:
[UIView animateWithDuration:2.0 animations:^{
[self.view viewWithTag:kPlayView].alpha = 0;
[self.view viewWithTag:kCancelView].alpha = 0;
[self.view viewWithTag:kTapViewTag].backgroundColor = [UIColor clearColor];
}];
I am able to show the view that acts as a "pause/resume" without animation, and then animate the fade out. This works back and forth as long as I don't try to animate the fade in.
UPDATE 2
Here is the entire implementation for reference. Something in here? (I've looked too many times).
- (void)didTap:(id)selector
{
isPaused = (isPaused) ? NO: YES;
[self.view viewWithTag:kPlayView].userInteractionEnabled = isPaused;
[self.view viewWithTag:kCancelView].userInteractionEnabled = isPaused;
if (isPaused)
{
[self pauseLayer:self.view.layer];
[timer1 invalidate];
[timer2 invalidate];
[UIView animateWithDuration:2.0 animations:^{
[self.view viewWithTag:kPlayView].alpha = 0.75;
[self.view viewWithTag:kCancelView].alpha = 0.75;
[self.view viewWithTag:kTapViewTag].backgroundColor = [UIColor whiteColor];
} ];
}
else
{
isPaused = NO;
[UIView animateWithDuration:2.0 animations:^{
[self.view viewWithTag:kPlayView].alpha = 0;
[self.view viewWithTag:kCancelView].alpha = 0;
[self.view viewWithTag:kTapViewTag].backgroundColor = [UIColor clearColor];
}];
[self resumeLayer:self.view.layer];
[self animateNotification];
}
}
UPDATE 3
- (void)pauseLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
layer.speed = 0.0;
layer.timeOffset = pausedTime;
}
- (void)resumeLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer timeOffset];
layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0.0;
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}
UIView animations are a nice high level wrapper around Core Animation, which renders its animations using your view's layer. By setting the layer speed to 0 you effectively are stopping the uiview animations from starting.
When you start the layer time again you start it from exactly where it left off. The animations from before you paused and after are coalesced and nothing happens.
The reason the animations work in the other direction when you don't animate in is because of the way the animations are set up and fired. When you call [UIView animate... it sets up a low level animation on the layer with a begin time and an end time and so on. The code you write completes instantly and the animation would begin on the next go of the runloop. Before you let everything return, however you also resume the layer's time and speed and so when it comes to do the animation everything proceeds as normal.
My guess is you don't mean to suspend the layer like this. There must be better ways of removing and stopping your animations. e.g. with UIView you just animate the property again and it stops, with CALayer you have removeAllAnimations and removeAnimationForKey: and also you can look into using -[CALayer presentationLayer] to find out where a particular layer is on screen at a particular point in an animation and then adjust the actual layer values to match.
Everybody..
How to set animation on button click ?
I have two buttons, both have different frame..
First CGRectMake (10 , 10 , 100 , 80 ); It has Black Image,
Second CGRectMake (200, 10 , 210 , 80 ); It has White Image,
When I click on First button of those, It should be animate to move from one frame to another frame..
Only seen like first's button Black Image move to second button location.. Like Image changes of Buttons..
After clicked button frame does not change... Should be remain as First and Second..
I have tried but not got the exact
buttonFirst.frame = buttonSecond.frame;
buttonFirst.center = buttonSecond.center;
buttonFirst.transform = CGAffineTransformMakeTranslation( buttonSecond.frame.origin.x - buttonFirst.frame.origin.x , buttonSecond.frame.origin.y - buttonFirst.frame.origin.y);
How to animate this ?
Editting :
I need to move one checkers from one CGRect to Another CGRect.. So, It want to display like moving checkers, But i dont want to change CGRect, Only button images looks like that...
Please tell me..
Thanks...
very simple logic
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.20f];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationBeginsFromCurrentState:YES];
[firstButton setFrame:CGRectMake(5, 50, 30, 30)];//moves to second button place
[secondButton setFrame:CGRectMake(5, 5, 30, 30)];//moves to first button place
[UIView commitAnimations];
use the logic accordingly to your use..
well..
you can try this link
[UIView beginAnimation/endAnimation] bock
CGRect oldRectFirst = buttonFirst.frame;
CGRect oldRectSecond = buttonSecond.frame;
[UIView animateWithDuration:0.2f animations:^{
buttonFirst.frame = oldRectSecond;
buttonSecond.frame = oldRectFirst;
}];
Here is example from working program:
[self.buttonFirst setUserInteractionEnabled:NO];
[UIView transitionWithView:self.buttonFirst
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionCurveLinear
animations:^{
buttonFirst.frame = buttonSecond.frame;
buttonFirst.center = buttonSecond.center;
}
completion:^(BOOL finished){
[self.buttonFirst setUserInteractionEnabled:YES];
}];
Finally i got the answer...
I have set two button in two separate view. after set one timer, and move first button image to another button's position..
Here is a sample code for that..
Step 1 : Set view with Timer
UIView *oldView = [[UIView alloc] init];
oldView = [viewArray objectAtIndex:selectedIndex];
UIView *newView = [[UIView alloc] init];
newView = [viewArray objectAtIndex:[sender tag]];
oldRect = [oldView frame];
newRect = [newView frame];
movingTimer = [[NSTimer alloc] init];
movingTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(movingCheckers:) userInfo:nil repeats:YES];
imageViewMove = [[UIImageView alloc] init];
[imageViewMove setFrame:oldRect];
[imageViewMove setImage:[UIImage imageNamed:blackManName]];
[self.view bringSubviewToFront:imageViewMove];
[self.view addSubview:imageViewMove];
Step 2 : Moving Image to second position
CGPoint aPoint = CGPointMake(newRect.origin.x - oldRect.origin.x, oldRect.origin.y - newRect.origin.y);
imageViewMove.frame = CGRectMake(imageViewMove.frame.origin.x + (aPoint.x / 6) , imageViewMove.frame.origin.y - (aPoint.y / 6), imageViewMove.frame.size.width, imageViewMove.frame.size.height);
if (imageViewMove.frame.origin.x >= newRect.origin.x)
{
[selectButton setBackgroundImage:nil forState:UIControlStateNormal];
[moveButton setBackgroundImage:imageViewMove.image forState:UIControlStateNormal];
[imageViewMove removeFromSuperview];
[movingTimer invalidate];
}
Now its work.....
I want to add some text which is a long text lets say a story and I want it to be presented in a moving up fashion. That is it will be displayed in a box and the text will be moved line by line to show the whole story. So one line gets out of the box from top and other comes from the bottom. Like a HTML marquee behavior.
You should look into whether or not UIScrollView's contentOffset property is animatable using UIView animation blocks.
If it's not, then you could try using an NSTimer and in its function, either set the contentOffset or call [scrollView scrollRectToVisible:desiredContentFrame animated:YES]; where desiredContentFrame.origin.y is just a little bit lower than what you previously had it at (depending on the scroll speed you want). Then play around with the firing frequency of your timer and the desiredContentFrame.origin.y's delta to see what looks best and has the best performance.
Here's a quick hack showing both ways:
- (void)startAnimTimer
{
currentRect = CGRectMake(0, 0, 1, 1);
[NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:#selector(doScroll) userInfo:nil repeats:YES];
}
- (void)startAnimUIView
{
[UIView beginAnimations:#"scrollUIViewAnim" context:nil];
[UIView setAnimationDuration:20.0];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
CGPoint newContentOffset = CGPointMake(0, scrollView.contentSize.height);
scrollView.contentOffset = newContentOffset;
[UIView commitAnimations];
}
- (void)loadView {
[super loadView];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(5, 5, 200, 200)];
scrollView.contentSize = CGSizeMake(200, 1000);
scrollView.backgroundColor = [UIColor magentaColor];
CGFloat y = 10;
CGFloat yDelta = 21;
for(int i = 0; i < 47; i++)
{
// Add some UILabels to the scrollview just so we can see it animating
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, y, 180, 20)];
label.text = [NSString stringWithFormat:#"Cheezburger %d", i];
[scrollView addSubview:label];
[label release];
y += yDelta;
}
[self.view addSubview:scrollView];
// Comment out one of these
//[self startAnimTimer];
[self startAnimUIView];
}
- (void)doScroll
{
CGFloat scrollDelta = 1.0f;
CGRect newRect = CGRectMake(0, currentRect.origin.y + scrollDelta, currentRect.size.width, currentRect.size.height);
// Scroll the scrollview to the next position
[scrollView scrollRectToVisible:newRect animated:YES];
currentRect = newRect;
}
This method may help (or not):
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated
If not, just make a big UILabel and animate its frame using a CABasicAnimation.
I think you want to look at the Scroll View (UIScrollView) in the iPhone SDK.
http://developer.apple.com/IPhone/library/documentation/UIKit/Reference/UIScrollView_Class/Reference/UIScrollView.html
Depending on your implementation, you may not be able to use it "out of the box" but it should provide the functionality you seem to be describing. I'm not sure it will do the auto-scroll thing but that should be pretty easy to implement... maybe.... But, I'm still confident it could be done.