I have a problem reloading a custom UIView (SBBarChart) inside of a table cell. I don't use autolayout because it was too difficult to adjust it will all components of the cell which may be there or not. I manually calculate each time the rectangles and that works.
In respect to the rotation, I have tried implementing in the table view controller the willRotateToInterfaceOrientation method with [self.tableView reloadData] inside. This generates the cells again after rotation. Fine.
Inside of the cell class, I invoke [self.barChart setNeedsDisplay] to ensure that the subviews of the chart will be reloaded, which works.
Now the problem. Initially, portrait view opens and loads correctly. When I rotate to landscape, that works as well. When I rotate back to portrait, the length of the bar is calculated correctly but still displayed as it was in landscape. So the new rectangle for the bar has the right measures but the bar is displayed too long and partly outside of the screen.
A label with the same measures for the frame is displayed (and centered) correctly, so it should be a problem of the bar view reloading.
What am I doing wrong?
Try checking the [[UIApplication sharedApplication] statusBarOrientation]
when reloading your tableview then adjust accordingly. That will give the current rotation status.
I just solved my problem. I found three major mistakes in my code.
1) I was using dequeueReusableCellWithIdentifier after removing controls from cells. This resulted in missing controls and strange behavior. Now I generate each time a new cell from the nib.
2) I was using x and y values of controls which I had removed from the cell. I just put the numeric values instead.
3) I was using the frame for determining the width of the screen. However, the frame does not change. To solve this, I used the following thread: How to get orientation-dependent height and width of the screen?
Now, I don't even need the line [self.barChart setNeedsDisplay] and I can rotate the device as much as I want, the controls don't shift anymore. :)
I am still not sure that I have to invoke reloadData for adjusting the layout but I haven't found a better solution.
So, finally it works! Thank you a lot for the help and I hope, this post will help someone else. :)
Related
In iOS13, the default way when presenting a view controller was changed to the "sheets/cards" view. As I’m not using auto layout (why not, is not really important and relevant), I rely on getting position of elements based on the frame of the view.
Now, the problem with the new method is, that the view frame doesn’t really reflect the actual content size visible on the screen anymore. E.g. if I have positioned a UIButton at the bottom on the view controller based on the view.frame bottom coordinate, it will be now cut off, as the view is actually moved down in the amount of the nice "sheets/cards" visual indication at the top. The same problem is even more evident in an iPad, where centring another view in the view controllers view will be offset, due to the fact that the default presentation style is now a "sheet" in the middle of the screen.
I’ve currently changed everything to force the full screen version, but it would be nice to use the new fancy design.
Anybody has any idea how to get the actual visible rect/coordinates in the new style without changing things to auto layout?
Here are how they look. The "flower" is centered in the view and the X button should not be so close to the bottom or missing completely in the iPad version.
Finally figured it out. As I was setting the positions of items in viewDidLoad, the frame was not calculated correctly, thus resulting things being laid out incorrectly. When resetting the frame and positions in viewDidLoadSubviews, the positions were placed correctly.
I have a tableView. Instead of having multiple subviews in each tableViewCell , i have added one main subview which draws each of the other subviews in its drawRect method.
(I have read somewhere that this makes scroll animation look better. Also apple has a sample project CustomTableViewCell).
First , problem is when i changes the orientation of device, then drawRect does not call automatically. And each tableviewcell appears to be stretced.
I solved this by using
mainView.contentMode = UIViewContentModeRedraw
This solves the problem. Now when the orientation change is done, drawRect is called automatically .
But during the orientation change, the animation of rotating view still shows each tableview cell stretched. It is a very small thing, but still it is noticeable. Can anyone suggest something on this ?????
You can't redraw during animation (not easily, anyway).
Split the table cell into components again and setup autoresizing correctly. The animation will then animate only component positions and it will look fine.
Where did you read drawRect: would make scroll animation better? Did you have some problems with scrolling animation?
Edit:
IMHO There is no way how to fix resizing animations and keep the performance increase from using drawRect: instead of subviews.
We have a modal view that contains a Table view that contains UITableViewCells used to edit an item. On the iPhone everything works fine, but on the iPad we're unable to get the UITableViewCell to register as anything besides 320 px wide. It will basically display correctly, but the items inside of the cell align as if it were only 320 px wide, and anything outside of 320 pixels does not respond to any touch events.
I've gone up the view hierarchy to see if possibly there is a view stuck at 320 px that might be forcing the table view cell to think its only 320 pixels wide, but we can't find anything.
We also even tried presenting the modal view in the main window to ensure it was presented at the highest level:
[appDelegate.tabBarController presentModalViewController:myEditor animated:YES];
I've checked the frame of the tabBarController, the "myEditor" view controller, and everything else involved and they all seem to be correct. The only issue seems to be the tableview cells.
Any help would be greatly appreciated. Thanks!
We found the best way to do this is to subclass the cell and override layoutSubviews (and remember to include [super layoutSubviews]). This has seemed to generally work in most situations.
I'm developing an image viewer, much like the Photos App.
It's a UIScrollView with paging enabled with images loaded from the internet, so I've adapted portions of the LazyTableImages sample. The Scroll View and each ImageView inside of it have all of their autoresize mask flags set.
When I first observed how resizes were happening during rotation, it looked good, but once I started trying to interact with the scroll view, I realized that I also had to programmatically change the size of the contentView. I did that by implementing didRotateFromInterfaceOrientation: in my view controller.
[self.scrollView setContentSize:CGSizeMake(numberOfImages * portraitWidth, [scrollView bounds].size.height)];
With interaction behaving properly, I then discovered that, if I was viewing the second photo and rotated, portions of both the 1st and 2nd photos would be shown on the screen. I needed to change the contentOffset as well.
I've tried to fix this two ways - both by using the scrollRectToVisible:animated: method of UIScrollView, as well as trying to set the contentOffset property directly. And I've experimented by putting this code in implementations of both the "one-step" and "two-step" responses to changes in Orientation. For example:
-(void)didAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
[self.scrollView setContentOffset:CGPointMake(currentlyViewedPhotoIndex * largeImageHeight,0) animated:YES];
In all cases though, it just looks janky as hell. Either I clearly see the scroll happen, or it just jumps. Uuuuuuuuuuugly! Is there a way to do this so that it behaves exactly like the Photos app does?
What I wound up doing instead - just before rotation starts, hide the UIScrollView and create a UIImageView that contains the currently viewed image. Rotate, that image will rotate all nice and pretty, and when rotation completes remove the ImageView and unhide the Scroll View.
Update - if you're reading this today (anytime after iOS 6), use a UIPageViewController and set transitionStyle to UIPageViewControllerTransitionStyleScroll, for crissakes.
I did something slightly different when faced with the same problem. In willRotateToInterfaceOrientation:duration:, I hide all of the UIScrollView's subviews except for the currently displayed subview, and in didRotateFromInterfaceOrientation: I unhide the subviews.
I need to create a view on the iPhone that scrolls horizontally through a gallery of images. The issue is that this gallery has the potential to have 100s to 1000s of images that needs to be presented, so I would like to avoid loading them all into a single UIScrollView at once and destroying performance. I need to create a view that recycles the view objects (like UITableView) to increase performance and reduce memory overhead, but it needs to scroll in a horizontal fashion.
Any ideas? Is it possible to make UITableView operation horizontally?
Thanks!
You could use a large scrollview, and monitor for the scroll position to change. You can add images as subviews as they are coming into the actual viewable area, and remove them as they are scrolled away.
This way, you only have to have a small number of image views present at any given time, but you give the appearance of them all being "there".
You could even recycle the image views by changing their image and location so you are not creating and destroying complex objects. This is what UITableView does with cells.
It is as simple as appyling a Transform.
Here is the code. Write this in the your tableViewController init:
self.view.frame = CGRectMake(100,-5,250,350); //any Frame of your choice
CGAffineTransform trans = self.view.transform; // get current transform (i.e. portrait)
trans = CGAffineTransformRotate(trans, (M_PI / -2.0)); // rotate 90 degrees to go landscape
self.view.transform = trans; // set current transform (landscape)
But now what you need to realize is that your axis are also swapped. Any changes you make to the height will change the width (and vice versa) and any changes made to the origin.x changes the origin.y (and vice versa)
I agree with mbmcavoy, you can also take a look iPhone/iPad – AppStore like UIScrollView with paging and preview this article explains what you need about UIScrollView as well as provides a good example and source code.
Regards
Is it possible to add a UITableView horizontally? In a different orientation than the screen. Then you can use regular UITableView semantics where each row is an image that scrolls horizontally instead of vertically.
Posting an answer to this old thread because the validated answer is not correct. You may use a UITableViewController and its dequeueReusableCellWithIdentifier built-in features.
The trick is to make your tableview rotate and then make your cell rotate in the opposite direction.
in viewDidLoad you will add:
self.view.transform = CGAffineTransformMakeRotation(-M_PI_2);
And then in cellForRowAtIndexPath you would use:
cell.containerView.transform = CGAffineTransformMakeRotation(M_PI_2);
Make sure that every content of your cell is added to a container view (in this example containerView) so that you only have to rotate the container and not every cell subview.
Also please note that it will work better with cells having square dimensions, cause otherwise you may struggle with height/width computation.
I think I have the answer for you About scrolling an UITableView Horizontally:
create an UIScrollView (and disable
the vertical scroll)
put an UITableView inside the scroll
view
change the table view width as you
wish and update the
UIScrollView.contentSize as the
tableView width