I have successfully built the sample application from Vuforia. I am interested in taking the Cylinder Tracking and replacing the soccer ball that rotates around the soda can with a button that does not rotate but sits at a certain position in relation to the can (the center of the tracking image).
I am new to iOS development and am not sure quite how to do this. Ideally this would be done programmatically.
I was able to add a button to the CylinderTargetsViewController.mm using the following code:
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setTitle:#"Gossamer Rules" forState:UIControlStateNormal];
[button sizeToFit];
button.center = CGPointMake(320/2, 60);
[button addTarget:self action:#selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (void)buttonPressed:(UIButton *)button {
UIApplication *mySafari = [UIApplication sharedApplication];
NSURL *myURL = [[NSURL alloc]initWithString:#"http://www.example.com"];
[mySafari openURL:myURL];
}
However this adds a button to the screen whether the target is found or not and it has no spatial relationship to the target.
I tried moving this code into CylinderTargetsEAGLView.mm but got an error on line [self.view addSubview:button]; saying view was not a property of self.
I realize this is probably not the right approach. I'm thinking the button needs to be rendered as an openGl object or something so that it is 3 dimensional and can be seen from an angle when moving the target.
Has anyone done this or have any clue how it may be done?
I have decided to use the Vuforia Unity Package as there is a much steeper learning curve trying to learn pure OpenGL programming. The Unity route has much larger community support, and more tutorials / information are available.
Related
i am doing one simple apps project and using storyboards. but i am confuse to use either storyboard or xib file in my project ?
which of the best as performance base.
There is no performance improvements in Storyboard versus Xib files, they both are modified XML files. However storyboards are meant to be easier to use and give better overall look of your app. My personal experience is that storyboards are OK for really small apps(let's say 3-4 screens at top), however if you have complex app with 10-15 screen storyboards becomes a nightmare to maintain.
UPDATE
Also what I don't like about storyboards, is that if I wan't to reuse some screen in other application, I'll have to copy .m and .h files, and then search through storyboard to find my related interface file and put it inside new storyboard. Without them I'll just copy paste h,m,xib files(which I usually put in separate folder) for each screen at new project and use them.
Solution for you last comment :
you can use following code for designing UIButton dynamically-
int yPosition = 0;
for (int i = 0; i<10; i++){
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton setBackgroundColor:[UIColor blackColor]];
[aButton setTitle:[NSString stringWithFormat:#"Button %d",index] forState:UIControlStateNormal];
[aButton setFrame:CGRectMake(20, yPosition, 100, 50)];
[aButton addTarget:self action:#selector(aButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[aView addSubview:aButton];
yPosition += 50;
}
- (IBAction)aButtonClicked:(id)sender
{
NSLog(#"Clicked on button with title %#",[sender titleLabel].text);
}
Hi i am making customUIButtons in my app by using the following piece of code.
+ (NSArray *) createButtonItemNormalImage:(UIImage *)normalImage
highlightImage:(UIImage *)highlightImage
disabledImage:(UIImage *)disabledImage
touchUpSelector:(SEL)selector
target:(id)target
{
// HighlightImage is not used. Highlight is shown using iOS glow
UIButton *uiButton = [UIButton buttonWithType:UIButtonTypeCustom];
uiButton.bounds = CGRectMake(0,
0,
normalImage.size.width,
normalImage.size.height);
[uiButton setImage:normalImage
forState:UIControlStateNormal];
if (disabledImage)
{
[uiButton setImage:disabledImage
forState:UIControlStateDisabled];
}
[uiButton addTarget:target
action:selector
forControlEvents:UIControlEventTouchUpInside];
uiButton.showsTouchWhenHighlighted = YES;
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:uiButton];
return [NSArray arrayWithObjects:buttonItem, uiButton, nil];
}
I have made a cancel button using the above function. The cancel button takes the user from one screen to another screen. The problem is when i come back to the first screen the cancel button is still glowing. I have seen this problem before also but a call to [self.view setNeedsLayout] used to solve it.
Why does it happen and what would be a correct way of solving it?
Thanks!
To solve this problem in not so standard way I now set the highlighted state to no for all the buttons when I enter the first screen. I use myButton.highlighted = NO;. However the documentation says following for highlighted property.
Specify YES if the control is highlighted; otherwise NO. By default, a control is not highlighted. UIControl automatically sets and clears this state automatically when a touch enters and exits during tracking and when there is a touch up.
Its not happening so in my case.I would love to know the reason behind it and standard ways of solving it
I'm making a simple flashcard application. Here's a partial screenshot of one of my app storyboards:
It contains one UIImageView ("turnImage") on top of two buttons ("yesButton", "noButton"), and an additional third button which covers the whole view and overlaps with all the other elements (invisible in this screenshot). When this view is originally displayed, the images on the two buttons are set to nil and the UIImageView is set to display a "tap to change" graphic (with the third invisible button actually catching the tap):
[yesButton setImage:nil forState:UIControlStateDisabled];
[noButton setImage:nil forState:UIControlStateDisabled];
turnImage.image = [UIImage imageNamed:#"card-flip-01.png"];
yesButton.enabled = NO;
noButton.enabled = NO;
When the image is tapped (or the user touches anywhere else on the screen), the image changes to the "correct" and "incorrect" buttons, from which the user can pick whether or not they knew the word (not shown in these screenshots):
turnImage.image = nil;
yesButton.enabled = YES;
noButton.enabled = YES;
[yesButton setImage:[UIImage imageNamed:#"card-answer-correct-01.png"] forState:UIControlStateNormal];
[noButton setImage:[UIImage imageNamed:#"card-answer-wrong-01.png"] forState:UIControlStateNormal];
The above screenshots show the normal behaviour. However, I only get this behaviour on every other compilation - the rest of the time, the initial screen (which is supposed to display only the "tap to change" graphic) shows all three images, and the "tap to change" graphic is stretched differently from normal:
Aside for the graphical glitch, the program works fine: tapping anywhere gets the user to the next screen, where the two buttons are displayed correctly.
I get this both in the simulator and when run on a device. In the simulator, the behaviour changes every other time that the program is run; resetting the simulator content and settings does not affect this. On a device, the behaviour changes whenever I tell Xcode to run it on the device. If I unplug the device from a computer and start/shut down the application without changing its code, the behaviour does not change. (It is the combination of these factors that's making me assume the change in behaviour is linked to compilations.)
I tried closing down Xcode and starting it again, as well as rebooting the computer. These had no effect. I'm running the most recent version of Xcode.
The above code snippets aren't exactly the same as in my program: they've been simplified a bit for readability. There shouldn't be any functional changes, but just to be sure, here's the original code as well:
- (void)viewDidLoad{
// I've cut irrelevant stuff that happens before
[yesButton setImage:nil forState:UIControlStateDisabled];
[noButton setImage:nil forState:UIControlStateDisabled];
flipped = NO;
turnImage.image = [UIImage imageNamed:#"card-flip-01.png"];
[self setResponseNavigationButtons:flipped];
}
- (void) setResponseNavigationButtons:(BOOL)status{
if (status){
turnImage.image = nil;
[yesButton setImage:[UIImage imageNamed:#"card-answer-correct-01.png"] forState:UIControlStateNormal];
[noButton setImage:[UIImage imageNamed:#"card-answer-wrong-01.png"] forState:UIControlStateNormal];
} else {
turnImage.image = [UIImage imageNamed:#"card-flip-01.png"];
[yesButton setImage:nil forState:UIControlStateNormal];
[noButton setImage:nil forState:UIControlStateNormal];
}
yesButton.enabled = status;
noButton.enabled = status;
}
setResponseNavigationButtons is called with YES when changing to the other view.
D'oh, found the error. While rebuilding the project for the Nth time, I finally noticed the warning I had missed before:
Warning: Multiple build commands for output file ... card-flip-01.png
Apparently I had two different images with the same name in my resources, and the compiler would alternate between which one it would grab. Renaming the wrong one fixed the problem - it was transparent, and was letting the yes/no images show through.
In my app, I need to parse some data from the network, and add some customized buttons.
Later, when user click on it, I would provide more details.
An image view is the background for the app
The position of these buttons(xPos, yPos) are parsed from the server(dynamic data)
no prints when I click on these buttons that I add programmatically
The code I have for adding it is like this
...
[businessButton setImage:businessImage forState:UIControlStateNormal];
[businessButton setFrame:CGRectMake([xPos floatValue], [yPos floatValue], [businessImage size].width/2, [businessImage size].width/2)];
[businessButton addTarget:self.imageView action:#selector(serviceProviderSelected:) forControlEvents:UIControlEventTouchUpInside];
...
- (void)serviceProviderSelected:(id)sender
{
NSLog(#"sp tapped\n");
}
I created another dummy app to do (what I think is the same thing), and the button works out fine...
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *customizedButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *image = [UIImage imageNamed:#"business-icon.png"];
[customizedButton setImage:image forState:UIControlStateNormal];
[customizedButton setFrame:CGRectMake(100, 100, 20, 20)];
[customizedButton addTarget:self action:#selector(customButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:customizedButton];
}
- (IBAction)buttonPressed:(id)sender {
NSLog(#"yes, pressed\n");
}
I've been suspecting that the buttons I create in code are already released, and printed out the array that I use for storing these Buttons, they are valid addresses though...
Thanks!
William
I just found out why.
Instead of [self.imageView addSubview:businessButton];, [self.view addSubview:businessButton]; works now.
I think I didn't really understand how the view relationship was after adding an imageView in storyboard.
UIImageView has user interactions disabled by default. you have to set this property to YES in order to get an UIButton or anything else working as it's subview
You need to do:
[businessButton addTarget:self action:#selector(serviceProviderSelected:) forControlEvents:UIControlEventTouchUpInside];
The target needs to be the class that defines the selector.
I'm new to iOS graphics and animation and would like to know to how to accomplish the effect of momentum rotation of an image upon flick as seen in the video below.
http://www.youtube.com/watch?v=ZIQs-OWgkgI (now broken)
Even when not flicked the images have a nice sway.
Thanks.
That is pretty slick. It is rotating the view around a point (center of top) and then changing the amount of time it takes to rotate algorithmically, reversing when appropriate. I can't give you code, but I think if you watch this video demo from Prof. Hegarty you will have the tools you need. He rotates around a point outside the view - you can simply rotate around the edge of the view (and don't shrink the view). Check it out:
Part 1: http://www.stanford.edu/class/cs193p/cgi-bin/drupal/node/291
Part 2: http://www.stanford.edu/class/cs193p/cgi-bin/drupal/node/293
You'll definitely want to download the videos off iTunes U (free), as there is a lot of explanation.
Good luck,
Damien
I checked with the author of this and was informed that it was implemented using the Box2D physics library. I'm going to give that a shot. Thanks for the responses!
//this code can be used to rotate an image having both back and front
rotate = [UIButton buttonWithType:UIButtonTypeCustom];
[rotate addTarget:self action:#selector(rotate1)forControlEvents:UIControlEventTouchDown];
rotate.frame = CGRectMake(137.5, 245, 45, 46);
[rotate setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:#"viewing.png"]] forState:UIControlStateNormal];
[self.view addSubview:rotate];
int count;
count=0;
-(void)rotate1
{
count=count+1;
NSLog(#"rotate");
[UIView transitionWithView:imagecircle // use the forView: argument
duration:1 // use the setAnimationDuration: argument
options:UIViewAnimationOptionTransitionFlipFromLeft
// check UIViewAnimationOptions for what options you can use
animations:^{ // put the animation block here
imagecircle.image = imagecircle.image;
}
completion:NULL];
if(count%2==0)
{
NSLog(#"image.str.%#",appDelegate.imageNameString);
[imagecircle setImage:[UIImage imageNamed:appDelegate.imageNameString]];
[labellocation removeFromSuperview];
[labeldate removeFromSuperview];
[self.imagecircle addSubview:labelfrom];
}
else
{
[imagecircle setImage:[UIImage imageNamed:#"TGP_BACK.png"]];
[labelfrom removeFromSuperview];
[self.imagecircle addSubview:labellocation];
[self.imagecircle addSubview:labeldate];
}
}