I want to get the width value of my widget / today extension.
I can't use self.view.frame.size.width because it returns the whole screen width and not the actual widget width (on the iPad the width of the extension is not equal to the screen width).
What can I do to get the actual width of the widget?
..............
Don't read self.view.frame in viewDidLoad.
frame = (0 0; 768 1024); // in viewDidLoad
You should read self.view.frame after viewDidAppear
after viewDidAppear, self.view.frame is right value for content.
frame = (0 0; 545 75.5); // in viewDidAppear
Instead of viewDidAppear, I found that viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator is triggered automatically when the widget gets resized initially
Related
I have next code below:
- (IBAction)onTappedAddValue:(id)sender
{
CGRect rect = self.progressView.frame;
rect.size.width = rect.size.width + 1;
self.progressView.frame = rect;
NSLog(#"%#", [NSValue valueWithCGRect:self.progressView.frame]);
}
by pressing on the button I resize my view, so everything works good if view has for example rect (0, 0, 100, 10);
but if I set width to the 0 in storyboard and heigh to 10 points, by some reason SDK thinks that height also should equal 0 after pressing button and invocation code above.
Please check this video and sources if you want to see how it works. When I set UIView's width to zero in storyboard and then try to increment it by pressing button, the width is incrementing but by some reason height is equal to zero but in stroryboard it has 10 pt.
What I'm trying to reach is similar to what is implemented on youTube app on iPad. The search field is expanding in animation from right to left. I'm trying to do so and i'm getting very strange and not smooth animation, Although left to right is working perfect.
|<-------------------------------|Search Field|
It seems that the origin value is changed first and than the width changed , un like the left-right expanding animation that the origin stays the same.
Thanks
You can use animation just put Search field in dynamically in view and put below code.
[UIView beginAnimations : #"Display notif" context:nil];
[UIView setAnimationDuration:0.30];
[UIView setAnimationBeginsFromCurrentState:FALSE];
CGRect frGnrVw = generalView.frame;
CGRect frTblNote = tblNotes.frame;
frGnrVw.size.height = 0.0;
frGnrVw.size.height += 78.0;
generalView.frame = frGnrVw;
[UIView commitAnimations];
In above code general view is my view which has hight 0 and when some action called at that time view height increase and and we will see that view expanding down in that i can not change view's x and y position But in your case first hide your view and when search action calls set hidden NO of your view and in my code i increase height so you can increase your width and also change it's x position means (decrese) i.e you increase width 320 than you decrese it x position to 320 .
just try it it will work.
you can also put it statically in your story board or in nib just set its width =0 and x= 320.
you have to do like below.
[UIView beginAnimations : #"Display notif" context:nil];
[UIView setAnimationDuration:0.30]; // set duration of animation in seconds.
[UIView setAnimationBeginsFromCurrentState:FALSE];
CGRect frGnrVw = generalView.frame; //get frame of view.
frGnrVw.size.width = 0.0;
frGnrVw.size.width += 320.0;//increase width.
frGnrVw.origin.x -=320.0; // decrese position.
generalView.frame = frGnrVw; //set new frame to view.
[UIView commitAnimations]; // this will require.
you just put your view with search field at the position x=320 ,y = as your requirement ,width = 0 and height = as your requirement.
try it it will work.
Also you can hide like same in reverse order.
means increase its x position and decrease its width with above code.
If my answer helps than please vote up my answer.
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));
}
So in layoutSubviews, I'm calling positionTextView to adjust the frame of my UIScrollView subview (a UIImageView), which contains the following code.
CGRect frame = informationTextView.frame;
frame.origin = CGPointMake(self.contentOffset.x, self.contentOffset.y + 414-44);
informationTextView.frame = frame;
overlayView.frame = frame;
So on the simulator, the subview's frame location remains fixed (according to the contentOffset), but when testing on a device, the frame is moving, as if it wasn't taking the contentOffset into account.
Am I missing a difference between the behavior of the simulator and a device?
I want to use a UIScrollView as my main container in the app, enabling me to swipe back and forth between subviews. To achieve this, I created a UIViewController subclass with a UIScrollView IBOutlet:
In the viewDidLoad method I construct the sub-pages:
for (int i= 0; i< pageCount; i++)
{
CGRect frame = self.scrollView.frame;
frame.origin.x = frame.size.width * i;
frame.origin.y = 0;
UIWebView* aWebView= [[UIWebView alloc] initWithFrame:frame];
[self.scrollView addSubview:aWebView];
}
When launching the app (portrait mode), everything works. That is, the UIWebViews are layed out side by side with the correct dimensions, and I can swipe back and forth between them.
When I rotate to landscape, it seems that neither the scrollview size nor the subviews are resized.
I don't know what I should do in order to resize the subviews and the scrollview itself, or at what point in code I should do anything, and I cant seem to find any examples for this.
Anyone know what to do?
[edit] Attempt to adjust sizes as suggested by mahboudz:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * pageCount, self.scrollView.frame.size.height);
for (int i= 0; i< pageCount; i++)
{
CGRect frame = self.scrollView.frame;
frame.origin.x = frame.size.width * i;
frame.origin.y = 0;
UIWebView* view= [[self.scrollView subviews] objectAtIndex:i];
view.frame= frame;
}
}
This kind of does what I want, but has the following issues:
1) one can see the subviews grow to correct screen size upon changing orientation
2) when the current page is, for example, page 2 of 5 pages, the page is not fully visible after orientation was changed, but is off-screen by like 40 pixels
3) I get strange effects depending on whether the app is launched in portrait or landscape mode (simulator), ill try to explain:
When the app is launched in portrait mode:
The shape/border of the subviews looks messed up/offscreen, see screenshots:
http://i53.tinypic.com/21jr76x.png
when I rotate to landscape, everything looks okay, scrolling works superb. even when I rotate back to portrait, everything is great now:
http://i55.tinypic.com/if3iiw.png
When the app is launchend in landscape mode:
I get the same messed up/offscreen glitches as in portrait mode
Switching back and forth between portrait and landscape fixes this for landscape mode
BUT: Portrait mode will have the subviews with the width of the landscape mode, thus subviews are too wide
I tried to fix 1) doing the code above in willRotateToInterfaceOrientation however it completely messed up the layout.
I fixed 2) by adding the following code to didRotateFromInterfaceOrientation:
// update the scroll view to the appropriate page
CGRect frame = self.scrollView.frame;
frame.origin.x = frame.size.width * self.currentPage;
frame.origin.y = 0;
[self.scrollView scrollRectToVisible:frame animated:NO];
Note: current page is determined in scrollViewDidScroll
I dont have any idea how to fix 3)
You would need to reset the frame size, content size and the content offset in order to get the subviews in a proper position.
CGFloat screenHeight =[UIScreen mainScreen].bounds.size.height;
CGFloat screenWidth =[UIScreen mainScreen].bounds.size.width;
self.scrollView.frame = CGRectMake(0, 0, screenWidth, screenHeight);
self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * numberOfPages, self.scrollView.frame.size.height);
self.scrollView.contentOffset = CGPointMake(visiblePageBeforeRotation * self.scrollView.bounds.size.width, 0);
This code should be placed in the method
-(void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
Check as well the answer on this question:
Clean autorotation transitions in a paging UIScrollView
It has good example named Rotolling for rotating UIScrollView with paging enabled.
Hope this helps.
P.S: I am facing a problem on repositioning the center of the UIWebView on the rotation.
You need to implement viewWillRotate/viewDidRotate and make adjustments to our content size and orientation as needed.