How to make an animated button in Apple WatchKit? - ios

I'd like to make a button with animation in WatchKit, but it seems I can't find a way to modify WKInterfaceButton or drag an image into button in storyboard. Any help is appreciated.

After some research I found the solution, it's pretty simple but easily ignored :)
First, drag a button into a scene created in storyboard.
Second, select button, modify its property content from Text to Group. If you can't find content property, click the Attributes Inspector button at top right of your screen, it looks like a breakpoint button or a down arrow with a bar.
Now you can control group created inside your button. You need to add a reference of this WKInterfaceGroup inside your controller code. Here is an example:
#interface AAPLButtonDetailController()
#property (weak, nonatomic) IBOutlet WKInterfaceGroup *buttonGroup;
#end
#implementation AAPLButtonDetailController
- (instancetype)init {
self = [super init];
if (self) {
// Initialize variables here.
// Configure interface objects here.
[_buttonGroup setBackgroundImageNamed:#"Bus"];
[_buttonGroup startAnimating];
}
return self;
}
So the button animation will be played after scene initialized. Remember only frame animation is supported for now, all frames in one animation should be named like "Bus0.png", "Bus1.png"....
Hope this can help :)

Reck's post worked for me in instances that I needed to control the repeat count or duration. If you simply want to start or stop an animation for a button, the following works for me, where twoButton is a WKInterfaceButton and I have a set of images name Bus0#2x.png, Bus1#2x.png, etc.
- (void)startButtonAnimating
{
// This works, but can't control repeat counts or duration
[self.twoButton setBackgroundImageNamed:#"Bus"];
// But you can stop after a delay by setting background image nil
[self performSelector:#selector(stopGroupButtonAnimating) withObject:nil afterDelay:1.5];
}
- (void)stopButtonAnimating
{
[self.twoButton setBackgroundImage:nil];
}

Related

JTcalendar in IOS

I am trying to use JTcalendar library to build a custom calendar. In the current implementation , the scroll happens when the user swipes on the screen. I need two buttons left and right to support the scroll feature.
To do this , I have added two buttons in the menu bar for left and right scroll and tried to call the viewDidScroll() function on click of either. However this is not working.
Can anyone please point me in the right direction? I can share the current implementation if needed.
Using the above suggestions, this is how I was able to do this.
The contentView that I am using is from manager object as it is available in my MenuView Class. So this is now the shared contentView.
On this I have called loadpreviouspageWithAnimation and LoadNextPageWithAnimation.
Like So,
- (void) leftAction {
[_manager.contentView loadPreviousPageWithAnimation];
}
- (void) rightAction {
[_manager.contentView loadNextPageWithAnimation];
}
Where the _manager object is already available in the menuView and leftAction and RightAction are the target methods for the buttons.
Thanks!!
You have define somewhere JTHorizontalCalendarView object like below line of code.
#property (weak, nonatomic) IBOutlet JTHorizontalCalendarView *calendarContentView;
So for next month
[_calendarContentView loadNextPage];
For previous month
[_calendarContentView loadPreviousPage];

iOS: showing/hiding UI elements dynamically

I have an app with a UITableView of results in a center column, and a little search bar at the top. I want to dynamically add/remove a button that says "reset search" and pin it to the top of the view.
There are a couple ways to go about it, and I'm worried that they both look ugly or hacky to me. To wit:
Add the button in the storyboard editor, and show/hide it in code. The trouble is I've already got a bunch of views specified this way in the storyboard, and so positioning/selecting them is a huge pain since they overlap each other.
Add the button in code. Except now my UI is specified in two places: the stuff that's in the storyboard, and the additional modifications that take place in the code.
What's the standard way of doing something like this? And how can I prevent my storyboards from becoming a big mess when I've got buttons/dialogs/etc. that need to be dynamically shown/hidden?
Well my first answer is to not use storyboards in the first place. However, I understand that's not helpful in this case.
If I were you, I would do option 2. It's a one off for this single button and it has a specific use case. It doesn't hurt to specify it in code. The following is for the
.h
#property (nonatomic, strong) UIButton *resetButton;
And
.m
//I'm guessing you're using a VC, so I'd put this in viewDidLoad
self.resetButton = [[UIButton alloc]initWithFrame:YOUR FRAME];
self.resetButton.alpha = 0.0;
//any other styling
[self.view addSubview:self.resetButton];
self.resetButton addTarget:self action:#selector(onReset) forControlEvents:UIControlEventTouchUpInside];
//and then add these three methods
- (void)onReset {
//called when reset button is tapped
}
- (void)showResetButton {
[UIView animateWithDuration:.3 animations:^{
self.resetButton.alpha = 1.0;
}];
}
- (void)hideResetButton {
[UIView animateWithDuration:.3 animations:^{
self.resetButton.alpha = 0.0;
}];
}
I don't know if I have understood, but if you want to hide an object with an action, you can do so :
- (IBAction)myaction:(id)sender
{
self.object1.hidden = false ;
self.object2.hidden = true ;
self.object3.hidden = false ;
}
Both ways are perfect, I personally prefer the Storyboard one because it lets you arrange the button more easily and it's easier to add constraints for auto-layout(if needed) in Interface Builder than in code.
For your second question: If your storyboard is cluttered and views are all over the place, I would suggest that you select your views from the side bar, rather thank trying to click on them. Also, if you want to move the selected view, adjust the coordinates in the Utilities panel instead of dragging it with the mouse.

Change Background Image of an iOS app with a button click

Title pretty much says it all, I am new to Xcode and am trying to make a button that changed the view's background image. I will have three button and when you click one they will change the background that is associated with the button. How would I accomplish this? I have looked around but have not found anything relevant or anything that worked..
Thanks in advance!
EDIT::
As for what I have, I have a project set up with a window and one view with a background image called "default#2x-568h#2x.png" I would like to be able to press a button and have it switch to "second.png". I have a button and I control dragged into my .h which made this:
#interface TeslameterViewController : UIViewController <CLLocationManagerDelegate> {
IBOutlet UIButton *button1;
}
- (IBAction)button1:(id)sender;
#end
thats where I am lost.
EDIT AGAIN:
Found the fix via this video:
http://www.youtube.com/watch?feature=player_embedded&v=iKuGiJMgMiQ
On the button Action event add this line.
(void)Action:(UIButton *)sender
{
UIGraphicsBeginImageContext(self.view.frame.size);
[[UIImage imageNamed:#"bg.png"] drawInRect:self.view.bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.view.backgroundColor = [UIColor colorWithPatternImage:image];
}
try this:
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"imageName.png"]];
and also see UIView Image Background for example project with complete code...
You need to be more specific on what you need.
Within your xib file, create a UIImageView and stretch its dimensions to fit the size of the screen. Also create a the necessary buttons. Create properties in your view controller to have a reference to the UIImageView and the buttons. Give the buttons an action that changes the picture that the UIImageView loads.
You have to create three buttons in nib file and add outlet to your view controller.
To create outlet you have right click on button then you will get list of event, then control drag to your view controller header file, then one small window will pop up, write method name and click enter. Now u will see method in your controller.write code to change background of button or your view in that method.
for more details:http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphone101/Articles/05_ConfiguringView.html

How to use a custom UIButton category with Interface Builder?

I'm coding a simple card game for my younger sister on a whim. I'm using UIButtons: default state is face down, selected state is face up. I need the buttons to have a boolean property that tells me if they've ever been flipped over. If not, it gets set to true (that way I'm not just drawing random cards on each flip). I tried creating a category of UIButton called CardGameButton. In the .h file:
#interface UIButton (CardGameButton)
#property (nonatomic) BOOL discovered;
#end
In the .m file:
#implementation UIButton (CardGameButton)
#dynamic discovered;
#end
This is really all I need. How do I use this in IB? I have a bunch of UIButtons on a screen that I want to be CardGameButtons. But when I try to switch my calls to UIButton in my view controller to CardGameButton, it tells me CardGameButton isn't a type (yes I imported the file). And when I try to switch the class of the UIButtons in the storyboard to CardGameButtons, the console tells me that they're an "unknown class". I tried subclassing UIButton, but that didn't work (I just need them to be RoundedRectButtons with the extra property, and since you can't subclass RoundedRectButton they wouldn't display properly). How do I make this work in IB?
You're treating CardGameButtons as though it's a subclass of UIButton when instead it's a category. Anything you declare as UIButton will have the discovered property as standard, but you can't 'create' a CardGameButtons as it's not a thing in itself.
Categories are not types. They're just used to add some extended behavior to the class.
I suggest that you try subclassing UIButton and call it CardGameButton. Add the BOOL property to its interface. You can still make it a round rect button, by setting buttonType to UIButtonTypeRoundedRect "round rect buttons aren't a separate subclass.". Then override
- (void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
if(event.type == UIEventTypeTouches){
self.discovered = YES; // or handle the logic as you want here
}
[super sendAction:action to:target forEvent:event];
}
You can add a UIButton to your view from the IB, and then its class to your created subclass and set its type to round rect.
Edit: As you stated, buttonType is actually readOnly, so we can't use that to draw a round rect button. However, it turns out that it's not hard to draw it.
Check this tutorial. It shows how to do it using CALayer property of UIButton and using UIBezeirPath.

What is the best way to determine if a line that was drawn in a view was tapped?

I have a view with several lines drawn in it in different directions. I need to determine which line was tapped by the user and then respond accordingly.
I have a few different ideas in my head, but I want the best, most efficient way to do this...
Ultimately what makes the most sense to me is having each line in a separate view and treated like individual objects. If I did this would I need to position and rotate the view to be exactly where the line is so I know when it is tapped? If not I would assume the views will overlap each other and I would not be able to determine what line was tapped.
I hope I am making sense. Please let me know the best way to achieve this. Thanks!
For me the best way to approach this is create UIView's as lines. If they are simply lines with plain colors just use the background view and set the CGRectFrame accordingly.
In order to react to touch event's without dealing with positions etc, create a touchEvent in the init method of the UIView like this:
UITapGestureRecognizer *onTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(lineClicked)];
[self addGestureRecognizer:onTap];
Declare the function inside the UIView class:
-(void)lineClicked {
//You can check some #property here to know what line was clicked for example
if (self.color == [UIColor blackColor])
//do something
else
//do another thing
// You can use a custom protocol to tell the ViewController that a click happened
(**) if ([self.delegate respondsToSelector:#selector(lineWasClicked:)]) {
[self.delegate lineWasClicked:self];
}
}
(**) You will probably want to put some logic into your viewController after clicking in the line. The best way to approach this is to declare a #protocol in your CustomUIView.h file and pass self as parameter so the viewController knows who was clicked:
#protocol LineClikedDelegate <NSObject>
#optional
- (void)lineWasClicked:(UIView *)line; //fired when clicking in the line
#end
Finally, create a #property in your CustomUIView to point the delegate:
#property id<DisclosureDelegate> delegate;
And in the ViewController. When you create lines as UIViews set the delegate like:
blackLine.delegate = self.
Implement the method - (void)lineWasClicked:(UIView *)line; in the ViewController and you are set.
As requested I'm adding this as an answer:
You could use layers instead of views for displaying the lines. This is both efficient in drawing and allows for hit testing to determine which line has been tapped.
Here's code for the geometry calculations.

Resources