Change the position dynamically - ios

Im new to IOS development , so when i change the width of a UITextFeild dynamically i want the button below to shift up .
i tried using the constrains but it doesn't seem to shift dynamically .
(IBAction)selectStatus:(id)sender {
CGRect frameRect = _textViewDevices.frame;
frameRect.size.height = 10;
self.textViewDevices.frame = frameRect;
any good example of how to achieve that ?
I want to achieve something like the Relative positioning in android .
current box before any action

Try calling layoutIfNeeded after the modifications:
- (IBAction)selectStatus:(id)sender {
CGRect frameRect = _textViewDevices.frame;
frameRect.size.height = 10;
self.textViewDevices.frame = frameRect;
[self.view layoutIfNeeded];
}
If you have a height constraint on the text view, try to set its constant instead of setting the frame height:
- (IBAction)selectStatus:(id)sender {
self.textViewHeightConstraint.constant = 10;
[self.view layoutIfNeeded];
}

Programmatically when the first violet field changes in height, to make all the below views stay next to it, you should update the frame.origin.y properly.
So, for example, the status label should be reframed like this
CGRect frame = statusLabel.frame;
frame.origin.y = firstField.origin.y + firstField.size.height + 5;
statusLabel.frame = frame;
And the same for all below views (I've supposed 5 pixels of space between views)

Related

How can I expand width of UIView from left to right - Swift

I have a UIView and I've added a UIView inside it as a subview. I'm hoping to expand the subview to fill a portion of the view, as a percentage, for example:
subview.bounds.width = view.bound.width(num1/max)
where num1 changes every second until it reaches max.
A UIView's frame can't be partially changed - to get the result you're looking for, you need to create a new frame, manipulate it, then attach it to your subview, like so:
let newFrame = subview.frame
newFrame.size.width = view.frame.width * num1 / max
subview.frame = newFrame

Deciding height for UIScrollView with UIWebView inside

I have a detail view where I want to show a title, subtitle and content for articles. I want to be able to use HTML to format the text, so I've used a UIWebView for showing the article body. This works perfectly.
How ever, all of this, is inside a UIScrollView, so my issue is that I have to calculate the height of the UIScrollView?
This is how it works today:
And this is how it looks like in Storyboard:
So what I need to find out, is what is the correct code and syntax to calculate the correct height of the UIScrollView? Amongst several things, I tried [self.scrollView sizeToFit] without luck.
EDIT: Apparently it sets the correct heights with the code below, but seems like the view never updates.
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
// get height of content in webview
CGFloat height = [[webView stringByEvaluatingJavaScriptFromString:#"document.body.scrollHeight;"] floatValue];
// set new frame height
CGRect frame = webView.frame;
frame.size.height = height;
webView.frame = frame; // webview is now correct height
// set new frame height for scrollview (parent of webview)
CGRect scrollFrame = self.scrollView.frame;
scrollFrame.size.height = webView.frame.origin.y + height;
self.scrollView.frame = scrollFrame;
// log to console for cross checking
NSLog(#"new frame: %f, scrollview frame: %f", scrollFrame.size.height, self.scrollView.frame.size.height);
}
The console reports the apparently correct height:
new frame: 582.000000, scrollview frame: 582.000000
And a quick check in Photoshop as well, this seems to be correct:
The summed value of green and blue area is 582 pixels, but the scrollview still just scrolls the 504 pixel area from below the navigation bar to the bottom of the screen (to the bottom of the tab bar).
The webview has internally a scrollview. You can query its size by webview.scrollView.contentSize. You have to wait with this until the webview has finished rendering.
So, in the -webViewDidFinishLoad: delegate method you can get the optimal height of the webView through webView.scrollView.contentSize.height. You can then resize the webView to this height and layout the other views appropriately. If all of this is done in a custom view, the proper way of doing this would probably be to just call [theView setNeedsLayout] and override -layoutSubviews in theView.
You also should set webView.scrollView.alwaysBounceVertically to NO.
I solved the problem.
First of all, just expand the UIWebView to a height higher than the content ever will be (e.g. 2000 pixels).
The delegate method code that makes the magic happen
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
// set height for webiew
webView.autoresizesSubviews = NO;
webView.translatesAutoresizingMaskIntoConstraints = YES;
webView.scrollView.autoresizesSubviews = NO;
webView.scrollView.translatesAutoresizingMaskIntoConstraints = YES;
CGFloat height = [[webView stringByEvaluatingJavaScriptFromString:#"document.getElementById('content').clientHeight;"] floatValue] + 80; // +80 for tabbar and spacing
CGRect frame = webView.frame;
frame.size.height = height;
webView.frame = frame;
// fix height of scroll view as well
self.scrollView.translatesAutoresizingMaskIntoConstraints = YES;
self.scrollView.contentSize = CGSizeMake(320, (self.webView.frame.origin.y + self.webView.frame.size.height));
}

Setting the origin of the frame in iOS

I am trying to set the origin of the frame programmatically.
Method1:
button.frame.origin.y = 100;
Method 2:
CGRect frame = button.frame;
frame.origin.y = 100;
I tried method 1 but it is not working(showing an error saying Expression is not assignable). Method 2 is working. Why is this so?
Need guidance on what I am doing right.
The reason you can't do method #1 is because a frame's individual properties are read-only. However, the entire frame itself is writable/assignable, thus you can do method #2.
You can even do tricks like this:
CGRect newFrame = button.frame;
newFrame.origin.y += 100; // add 100 to y's current value
button.frame = newFrame;
You know
button.frame.origin.y return a value.
if you are using this one so you will get this error...
Expression is not assignable.
button.frame.origin.y = 100;
So this is correct way
CGRect frame = button.frame;
frame.origin.y = 100;
otherwise you can do like this...
button.frame = CGRectMake(button.frame.origin.x, 100, button.frame.size.width, button.frame.size.height)
It's because if you were able to directly change a frame's origin or size, you would bypass the setter method of UIView's frame property. This would be bad for multiple reasons.
UIView would have no chance to be notified about changes to it's frame. But it has to know about these changes to be able to update it's subviews or redraw itself.
button.frame.origin.y = 100;
equals to the following call:
[button getFrame].origin.y = 100;
in which [button getFrame] gives you the copied CGRect.
You are trying to set a variable of a structure of a structure. There is no pointer from the UIView to the structure (as it is a basic C struct so can't be pointed). hence, copied instead.
So basically, you are copying the structure and setting it. But, that just doesn't work like that.

Centering UIView

I have a UIViewController subclass that instantiates a UIView subclass (let's call that viewA). Then, viewA will sometimes instantiate another UIView which we'll call viewB.
I want viewB to be centered within the view controller.
My question is, "What is a (correct) way of doing this?"
TIA
There are many correct ways, but maybe the best one is to use the center-property:
[viewB setCenter: viewA.center];
Or maybe you need to use..
[viewB setCenter: viewA.navigationController.center];
You have to be careful to not end up on a fraction of a point. On non-retina you need to be on full points but for retina you can be on 0.5
One way would be to use center and then adjust
viewB.center = viewA.center;
viewB.frame = CGRectIntegral(viewB.frame);
I don't know a shorter way to do it than this one:
CGFloat x = CGRectGetMidX(self.view.bounds) - viewBWidth / 2;
CGFloat y = CGRectGetMidY(self.view.bounds) - viewBHeight / 2;
viewB.frame = CGRectMake(x,y,viewBWidth,viewBHeight);
viewB.frame = [MyClass centeredFrameForSize:desiredSize inRect:viewA.bounds];
+ (CGRect)centeredFrameForSize:(CGSize)size inRect:(CGRect)rect
{
CGRect frame;
frame.origin.x = rintf((rect.size.width - size.width)/2) + rect.origin.x;
frame.origin.y = rintf((rect.size.height - size.height)/2) + rect.origin.y;
frame.size = size;
return frame;
}

*modify* UIbutton position (Iphone SDK)

I'm playing around with UIbuttons, just to get a feel on what can really be done with them. I have only one problem so far:
How do I modify the position of a UIButton?
- (IBAction)buttonClicked:(id)sender
{
UIButton *senderB = sender;
CGPoint position = senderB.frame.origin;
CGSize size = senderB.frame.size;
senderB.frame = CGRectMake(position.x,position.y + 10,size.width,size.height);
}
The above works just fine, however, creating a new CGrect for every time I want to simply change one seems rather inefficient to me.
Is there any way for me to directly set the values of senderB.frame.origin.x, etc?
I usually do it like this:
CGRect buttonFrame = button.frame;
buttonFrame.origin.y += 10;
button.frame = buttonFrame;
Nope. Notice that 'someview.frame' returns a CGRect by value, not by reference or pointer or whatever. That's why you get the 'Lvalue required' error.
However, setting the frame like you're doing is plenty fast.
The frame property is read only. What you can do is copying the current frame with
CGRect btFrame = senderB.frame;
btFrame.origin.x += 10;
senderB.frame = btFrame;

Resources