So I am trying to move a UIButton after it is clicked.
The _addMoreFields method is called after the button is clicked.
_addMoreFieldBtn is a global UIButton. When I click it nothing happens.
The strange part is if I comment out the addSubView code then the button moves.
If I keep that code the button doesn't move.
Any Ideas?
-(void)movePlusButton {
NSLog(#"Moving button");
[UIButton beginAnimations:nil context:nil];
[UIButton setAnimationDuration:0.3];
_addMoreFieldsBtn.center = CGPointMake(30,30);
[UIButton commitAnimations];
}
- (IBAction)addMoreFields:(id)sender {
CGRect currentBtnFrame = [(UIButton *)sender frame];
CGPoint org = currentBtnFrame.origin;
UILabel *whoWasIn = [[UILabel alloc] initWithFrame:CGRectMake(110, org.y, 85, 21)];
whoWasIn.text = #"test";
UITextField *whoWasInField = [[UITextField alloc] initWithFrame:CGRectMake(59, whoWasIn.frame.origin.y+40, 202, 30)];
whoWasInField.placeholder = #"test2";
UILabel *with = [[UILabel alloc] initWithFrame:CGRectMake(136, whoWasInField.frame.origin.y+40, 49, 21)];
with.text = #"with";
whoWasInField.borderStyle = UITextBorderStyleRoundedRect;
UITextField *withField = [[UITextField alloc] initWithFrame:CGRectMake(59, with.frame.origin.y+40, 202, 30)];
withField.placeholder = #"test3";
withField.borderStyle = UITextBorderStyleRoundedRect;
[_homeView addSubview:whoWasIn];
[_homeView addSubview:with];
[_homeView addSubview:whoWasInField];
[_homeView addSubview:withField];
[self movePlusButton];
}
NOTE: I also tried changing the frame but I get the same issue. It starts animating from the new location I put to the existing spot.
The issue is that new projects in iOS 6 / Xcode 4.5 have "Autolayout" enabled by default. Autolayout is a replacement for "Springs and Struts" (but it only works iOS 6). This feature adds constraints to a view which take precedence over the move you were attempting in your code.
So there are three possible fixes to this:
1) Create new constraints on the button programmatically. Autolayout is pretty powerful and flexible... especially if you are trying to support the footprint of both the iPhone 5 and earlier models. You can find more info on how to do this by checking out the WWDC video: Introduction to Auto Layout for iOS and OS X
2) Don't use Autolayout. Select a view in your Storyboard, and in the File Inspector, uncheck "Use Autolayout."
3) Create IBOutlets for each of the constraints on the button. Then before you move the button, remove those constraints:
#interface MyViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIButton *addMoreFieldsBtn;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *hConstraint;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *vConstraint;
- (IBAction)addMoreFields:(id)sender;
#end
and...
-(void)movePlusButton {
NSLog(#"Moving button");
[self.view removeConstraint:self.hConstraint];
[self.view removeConstraint:self.vConstraint];
[UIButton beginAnimations:nil context:nil];
[UIButton setAnimationDuration:0.3];
_addMoreFieldsBtn.center = CGPointMake(30,30);
[UIButton commitAnimations];
}
(the actual view you need to call removeConstraints: on is the parent view of the button, which may or may not be self.view).
Actually, I think that whats happening is that your subview is coming onto to screen first, and therefore taking precedence, and then once the subview is removed, the button would move, if you change the code:
[_homeView addSubview:whoWasIn];
[_homeView addSubview:with];
[_homeView addSubview:whoWasInField];
[_homeView addSubview:withField];
[self movePlusButton];
}// move the [self movePlusButton]; up 6 lines of code, or make it first line
[self movePlusButton];
[_homeView addSubview:whoWasIn];
[_homeView addSubview:with];
[_homeView addSubview:whoWasInField];
[_homeView addSubview:withField];
This should solve all of your problems
:)
Related
I wan to design a settings page, in which I have to draw lines between multiple labels, what is the best way to do this, I have googled around, got to know about CGContextRef approach. Is this the proper way, I need to have a line between labels (consecutively). Can I go ahead with this approach or any other best way is there.
I have given base view as dark color and I am adding labels as white, I am giving a line gap between two labels its looking like a line. No extra work :)
May be just add UIView between labels? Something Like this:
UILabel *topLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
//Label settings
[self addSubview:topLabel];
[topLabel release];
UIView *separator = [[UIView alloc] initWithFrame:CGRectMake(topLabel.frame.origin.x, CGRectGetMaxY(topLabel.frame), topLabel.frame.size.width, 2)];
separator.backgroundColor = [UIColor blackColor];
UILabel *bottomLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(separator.frame), 320, 20)];
//Label settings
[self addSubview:bottomLabel];
[bottomLabel release];
Couldn't you just create a custom UIView class with a UILabel and a UIView as the subviews of this custom view class?
class CustomView : UIView
{
UIView *line;
UILabel *label;
}
#property(nonatomic, retain) UIView *line;
#property(nonatomic, retain) UILabel *label;
For the UIView subview, you can tell it to use the width of the parent UIView.
so guys, i've been wondering, currently i'm in the middle of learning on developing apps. i saw a CNBC apps at ipad that looks like the image here : (sorry, new user cant directly post image D:)
http://images.thoughtsmedia.com/resizer/thumbs/size/600/at/auto/1291813093.usr105634.jpg
my question is, what are those 2 bars on top of the app??(the one with markets, and indexes)
is it a tabbar controller?? if it is how do we put it on top of the app instead of at the bottom like it normally is, and how do we have another tabbar inside a tabbar???
i appreciate your helps, and sorry for my bad english :3
okay, i have found the solution to this, by far i've tried both customized tabbar and segmented controller, but i found both of them risky and too complicated
so i do a little experiment with simple button
here's the main idea
first, i set up a toolbar, and give it a background
-in viewController.h
//adding my viewcontrollers
#class notLoggedHome;
#class LoggedInHome;
#class NABViewController;
//defining all the objects
#properties (nonatomic, strong) UIToolBar *mainToolBar;
#properties (nonatomic, strong) UIButton *toolBarBut1, *toolBarBut2, *toolBarBut3;
#properties (nonatomic, strong) UIImageView *logoImage;
#property (nonatomic, strong) notLoggedHome *viewNotLoggedHome;
#property (nonatomic, strong) LoggedInHome *viewLoggedInHome;
#property (nonatomic, strong) NABViewController *viewNAB;
#properties NSInteger lastTag;
-in viewController.m
#synthesize mainToolBar, toolBarBut1, toolBarBut2, toolBarBut3;
#synthesize logoImage, lastTag;
#synthesize viewNotLoggedHome, viewLoggedInHome, viewNAB;
-(void)viewDidLoad
{
lastTag = 100;
self.view.backgroundColor = [UIColor colorWithRed:21.0/255.0 green:21.0/255.0 blue:21.0/255.0 alpha:1];
//---
//---fakeTabBar set up===
viewNotLoggedHome = [[notLoggedHome alloc]init];
viewLoggedInHome = [[LoggedInHome alloc]init];
viewNAB = [[NABViewController alloc]init];
//creating the fakeTabBar
mainToolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 70)];
[mainToolBar setBackgroundImage:[UIImage imageNamed:#"menu_bar.jpg"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
//defining images
imgHome = [UIImage imageNamed:#"menu_home.png"];
imgHomeS = [UIImage imageNamed:#"menu_home_s.png"];
imgLogo = [UIImage imageNamed:#"menu_bar_logo_ep.png"];
UIImageView *logoImage = [[UIImageView alloc]initWithImage:imgLogo];
logoImage.frame = CGRectMake(0, 0, imgLogo.size.width, imgLogo.size.height);
//--button setting====
toolBarBut1 = [UIButton buttonWithType:UIButtonTypeInfoLight];
[toolBarBut1 setFrame:CGRectMake(imgLogo.size.width, 1, imgHome.size.width, imgHome.size.height)];
toolBarBut1.tag = 0;
toolBarBut1.backgroundColor = [UIColor colorWithWhite:1 alpha:0];
[toolBarBut1 setImage:imgHome forState:UIControlStateNormal];
[toolBarBut1 setImage:imgHomeS forState:UIControlStateSelected];
[toolBarBut1 addTarget:self action:#selector(barPressed:) forControlEvents:UIControlEventTouchUpInside];
//do the same with the other 2 button
//---------------------
[mainToolBar addSubview:logoImage];
[mainToolBar addSubview:toolBarBut1];
//do the same with the other 2 button
[self.view addSubview:mainToolBar];
[super viewDidLoad];
}
-(void)barPressed:(id)sender
{
UIButton *button = (UIButton *)sender;
if(button.tag == 0 && button.tag != lastTag)
{
[viewNAB removeFromParentViewController];
[viewNotLoggedHome removeFromParentViewController];
[self.view addSubview:viewLoggedInHome.view];
button.selected = YES;
}
if(button.tag == 1 && button.tag != lastTag)
{
[viewNAB removeFromParentViewController];
[viewLoggedInHome removeFromParentViewController];
[self.view addSubview:viewNotLoggedHome.view];
button.selected = YES;
}
if(button.tag == 2 && button.tag != lastTag)
{
[viewLoggedInHome removeFromParentViewController];
[viewNotLoggedHome removeFromParentViewController];
[self.view addSubview:viewLoggedInHome.view];
button.selected = YES;
}
lastTag = button.tag;
}
so the main idea is creating a fake tabbar by using toolbar, assigning UIButton(s) to the toolbar as the fake tabbaritem, and giving mechanism to each button that later will switch your viewcontrollers (you have to alloc the viewcontrollers first at implementation file)
this works well for me, just dont forget to set the view controllers frame Y point +(toolbar Height) because otherwise it will cover the toolbar later
:)
I have 30-40 tabs open, I've found my answer.. but I'm wishing to improve.
The code does work, I am just not sure if it is efficient
The following code shows that I have 2 small images (One using UIImageView, another using UIView) in which I have attached to a UIScrollView, which is attached to a UIView which came with the UIViewController, which is attached to the UIWindow. Pretty basic.
I also have a button attached to the UIViewController to make sure zooming and scrolling worked. (By testing the static location of the button and size)
#interface Wire_TestViewController : UIViewController <UIScrollViewDelegate> {
UIScrollView *scrollview;
}
#end
Implementation:
- (void)test:(UIButton *)sender { }
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { return scrollview; }
- (void)viewDidLoad {
[super viewDidLoad];
scrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
scrollview.delegate = self;
scrollview.contentSize = CGSizeMake( 320*2, 480*2 );
scrollview.minimumZoomScale = .1;
scrollview.maximumZoomScale = 10;
[self.view addSubview:scrollview];
UIImageView *view = [[UIImageView alloc] initWithFrame:CGRectMake(320, 320, 20, 20)];
view.image = [UIImage imageNamed:#"Node.png"];
view.clearsContextBeforeDrawing = NO;
[scrollview addSubview:view];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(10, 10, 100, 30);
button.tag = 51;
[button setTitle:#"new button" forState:(UIControlState)UIControlStateNormal];
[button addTarget:self action:#selector(test:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 30, 30)];
view2.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"WireActive.png"]];
[scrollview addSubview:view2];
TestSubclass *test = [[TestSubclass alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];
test.userInteractionEnabled = TRUE;
test.image = [UIImage imageNamed:#"Node.png"];
[scrollview addSubview:test];
}
You'll see near the bottom I have a TestSubclass class made.
The code for that is as follows:
#interface TestSubclass : UIImageView { }
#end
#implementation TestSubclass
- (id)init {
[super init];
self.userInteractionEnabled = TRUE;
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
printf("Being touched...\n");
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
printf("Touches Ended...\n");
}
#end
The part in which I am happy with is that I have a fully functioning Subclass of UIImageView which works as if it was a UIButton.
BUT! without the 7 backgroundImageViews (and the overhead from each of those), without the 6 labels (and the overhead from each of those), without the 6 UIImageViews ("..."), and lastly the amount of un-needed things that UIButton offers. I only wanted touch capabilities.. efficiently however. (TouchUpInside, Dragging, etc)
But, now during my research (after the extensive testing to accomplish this much), I've come across in documentation and some examples addGestureRecognizer in UIView. It seems sorta-but not entirely efficient for my needs.
I'm looking for advice, I know there are a couple problems in my code (overrided init, but didn't use it in the above code.. didn't release.. probably some subclassing mistakes (new to subClassing (to be honest)). But anything is much appreciated!! And, I hope others are helped as well!
If you want to have full control capabilities, you must subclass UIControl and use your image with in. The image can be an UIImageView subview or can be drawn in the drawRect method of your subclass or set in the CALayer view content.
Note that subclassing UIControl is not the easiest thing to do, but it gives you all "control" feature it seems you are requesting from it and I think is the most efficient or appropriate approach.
plz help me out
I am a newbie in iphone development its my second sample code. I am trying to add sub-views to a View and generate events according to the view/subview which is touched.i have added subviews in main view and all are showing all at one time. The projects I am experimenting with is a newly created, clean Window-Base application.
I wrote the following code into the one and only viewController's code:
#interface testViewController : UIViewController {
IBOutlet UIView *blueView1;
IBOutlet UIView *blueView2;
: :
IBOutlet UIView *blueView6;
}
//---expose the outlet as a property---
#property (nonatomic, retain) IBOutlet UIView *blueView1;
#property (nonatomic, retain) IBOutlet UIView *blueView2;
: : *blueView6;
//---declaring the action---
-(IBAction) viewClicked: (id) sender;
#end
And its .m file contains (loadView method in which i am attaching subviews to it. They are displaying very well all at one time.what i am trying to do is when my view/subview are touched they will generate an event which should be treated by this single method according to their object which will change the back color of the view/subview accordingly.
- (void)loadView {
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 80)];
self.view.backgroundColor = [UIColor greenColor];
// Create a simple blue square
CGRect blueFrame0 = CGRectMake(5, 115, 100, 100);
UIView *blueView0 = [[UIView alloc] initWithFrame:blueFrame0];
blueView0.backgroundColor = [UIColor blueColor];
// Create a simple blue square
CGRect blueFrame1 = CGRectMake(110, 115, 100, 100);
UIView *blueView1 = [[UIView alloc] initWithFrame:blueFrame1];
blueView1.backgroundColor = [UIColor blueColor];
// Create a simple blue square
CGRect blueFrame2 = CGRectMake(215, 115, 100, 100);
UIView *blueView2 = [[UIView alloc] initWithFrame:blueFrame2];
blueView2.backgroundColor = [UIColor blueColor];
//-----------------------------------------------------------------------------------------------------------
// Create a simple blue square
CGRect blueFrame3 = CGRectMake(5, 220, 100, 100);
UIView *blueView3 = [[UIView alloc] initWithFrame:blueFrame3];
blueView3.backgroundColor = [UIColor blueColor];
// Create a simple blue square
CGRect blueFrame4 = CGRectMake(110, 220, 100, 100);
UIView *blueView4 = [[UIView alloc] initWithFrame:blueFrame4];
blueView4.backgroundColor = [UIColor blueColor];
// Create a simple blue square
CGRect blueFrame5 = CGRectMake(215, 220, 100, 100);
UIView *blueView5 = [[UIView alloc] initWithFrame:blueFrame5];
blueView5.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView0];
[self.view addSubview:blueView1];
[self.view addSubview:blueView2];
[self.view addSubview:blueView3];
[self.view addSubview:blueView4];
[self.view addSubview:blueView5];
[blueView0 release];
[blueView1 release];
[blueView2 release];
[blueView3 release];
[blueView4 release];
[blueView5 release];
[self.view release];
}
-(IBAction) viewClickedid) sender {
{view/subview}.backgroundColor = [UIColor blackColor];
}
i worte the delegate in this way
#interface testAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
testViewController *viewController; //for main view
testViewController *viewController1;//for subview1
testViewController *viewController2;//for subview2
testViewController *viewController3;//for subview3
**upto 6 controllers
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet testViewController viewController;
#property (nonatomic, retain) IBOutlet testViewController viewController1;
**upto 6 controllers
#end
In testAppdelegate.m i am making a controller for main view but i dont know how to attach other controllers to other subviews.right now when i touch anywhere on the view the main view color changes.
how can i uniquely identify different subviews touch and make their color change??How to do this????
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
checkAppController *rootController = [checkAppController alloc];
[window addSubview:[rootController view]];
[window makeKeyAndVisible];
}
i am getting all the touches events in this method
- (void)touchesBeganNSSet *)touches withEventUIEvent *)event {
UITouch* touch = [touches anyObject];
NSUInteger numTaps = [touch tapCount];
if ([touches count] > 1)
NSLog(#"mult-touches %d", [touches count]);
if (numTaps < 2) {
}
else {
NSLog(#"double tap");
}
}
It is to do with the way you are structuring your application. For the BlueView1..6 to be handled by a separate view controller, it is that view controller which needs to create the view.
You need to create the view controllers for each blue view inside the main view controller, and then create each blue view inside the blue view inside each blue view controller.
Is it possible to allow user input text on a UIImageView, just like the text tool in painter?
I cannot find any resource on this topic?
UIImageView is not designed to hold any text, but you could add a UILabel or UITextField either within it or on top / below it, depending on what you want to do.
For example, suppose you want to allow the user to edit a piece of text inside an image. You could do something like this:
UIImage* image = [UIImage imageNamed:#"my_image.png"];
UIImageView* imageView = [[UIImageView alloc] initWithImage:image];
imageView.userInteractionEnabled = YES;
UITextField* textField = [[UITextField alloc]
initWithFrame:CGRectMake(10, 10, 50, 20)];
textField.placeholder = #"type here";
[imageView addSubview:textField];
// You might also want to set the imageView's frame.
[self.view addSubview:imageView];
If you add a UITextField as a subview of a UIImageView, it's important to set the userInteractionEnabled to YES, since it defaults to NO for that superview (it's usually YES by default in most UIViews).
Addendum
If you want the user to be able to click anywhere in the image to edit the text, here is one way to do it: subclass UIControl and add a UIImageView and a UITextField as subviews of it, and connect the clicking action of the UIControl to the UITextField. Something like this (WARNING: not tested code, but it conveys the general idea):
#interface ImageAndTextView : UIControl {
UIImageView* imageView;
UITextField* textField;
}
#property (nonatomic, retain) UIImageView* imageView;
#property (nonatomic, retain) UITextField* textField;
- (void) click;
#end
#implementation ImageAndTextView
#synthesize imageView, textField;
- (id) initWithFrame: (CGRect) frame_ {
if (self = [super initWithFrame:frame_]) {
UIImage* image = [UIImage imageNamed:#"my_image.png"];
self.imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
imageView.userInteractionEnabled = YES;
[self addSubview:imageView];
CGRect textFrame = CGRectMake(10, 10, 50, 20); // whatever frame you want
self.textField = [[[UITextField alloc]
initWithFrame:textFrame] autorelease];
[self addSubview:textField];
// Now register an event to happen if the user clicks anywhere.
[self addTarget:self action:#selector(click)
forEvent:UIControlEventTouchUpInside];
}
return self;
}
- (void) click {
[textField becomeFirstResponder];
}
#end
This is not possible with the current iPhone API (3.1). You will need to create your own custom uitextfields and your own image rendering methods to combine the layers into a captioned photo.