Determining height of ScrollView content - ios

I have a Nativescript-Vue application and I'm trying to determine the height of the contained content inside a ScrollView, however when I dump out a variety of height-related properties of the ScrollView both before and after I have changed the sizing of the contained content, there is no difference in the reported heights.
As a bonus question, what I actually care about is determining the state of a contained RadDataForm Picker element (collapsed or expanded) and after having no luck finding anyway to determine this state, I thought I could side-step the issue by looking at the overall height of the RadDataForm which is inside a ScrollView. So if you know how to determine the Picker state, that would be an even better answer.
This is the basic premise of what I've tried:
let view = this.$refs.scrollView.nativeView;
let size = view.getActualSize();
console.dir(size);
console.log(
`ht: ${view.height}, ${view.getMeasuredHeight()}, ${view.effectiveHeight}, ${view.scrollableHeight}, ${view.verticalOffset}`
);
The full test code is at this Playground:
https://play.nativescript.org/?template=play-vue&id=SvC31q&v=3
And the API for the ScrollView is here:
https://docs.nativescript.org/api-reference/classes/_ui_scroll_view_.scrollview
I would expect that you could click the button to dump the height state to the console, click on the country Picker and then click on the button again and see the difference in at least one of those properties, but so far, no joy.

Use scrollableWidth / scrollableHeight on ScrollView to know the actual scrollable width / height.

Related

iOS: How to display a box of 'tappable tags'

My use-case is like this:
The user defined some tags (text like "#asdf", "#qwerty", "#let_me_think_about_it" and "#decide later"). I want to display these in a box without scrolling (and don't know, how many tags the user created until I display the box).
The box itself should not be scrollable at all but be shown in a UITableViewCell (which is being scrolled). So it must compute the proposed height and respond to Autolayout mechanisms. If a (ARM) Mac user resizes the window to be smaller than before (or an iOS user rotates the device), the box should increase/decrease its height, as necessary (within the limits of Autolayout, since I know of some issues). Each of the tags should be (de)selectable at the same time (UILabel with UITapGestureRegognizer attachted?) and be able to displayed 'selected' (via a background view).
So, the box should primary try to align all content horizontal. If There's not enough horizontal space, do a "line break" and continue on the next "line".
My current solution is a UIScrollView that the user can scroll horizontal and tap any of the (UILabel) views. The displayed views itself are being loaded from a NIB file, like a UITableView does. The issue here is that not any of the selected tags might be visible at the first glance.
If there was no Autolayout, I'd exactly know what to do. But since there it is, I want to use Autolayout in my NIB files and wonder what you would do?
(How do you compute the required width of such a view and decide when a line break is to be done (and how?))
I think I need a simple hint. But if it needs code to explain, ObjC and Swift is both acceptable. :-)
So, the box should primary try to align all content horizontal. If There's not enough horizontal space, do a "line break" and continue on the next "line".
This sounds like a job for UICollectionView with UICollectionViewFlowLayout. You can disable scrolling, and the layout object will tell you the size of the content so that you can adjust the size of the box.
(How do you compute the required width of such a view and decide when a line break is to be done (and how?))
If you're doing it yourself, you add up the widths of all the items on the first line, and if it's larger than the available space, you move the item that extends past the limit and any subsequent items to the next line. Repeat as needed. But that's exactly what a flow layout does for a collection view, so there's no need to roll your own.

TableView into ScrollView - iOS

I would like to insert a UITableView into a UIScrollView.
To do this I added a ContainerView inside the UIScrollView and a UITableView linked to this ContainerView.
The result obtained in the storyboard is this :
http://i.stack.imgur.com/12hZz.jpg (Storyboard)
http://i.stack.imgur.com/AGY4L.jpg (Storyboard)
When I launch the emulator the TableView is loaded correctly, but not with the result expected
http://i.stack.imgur.com/ebij9.gif (Animated GIF)
http://i.stack.imgur.com/bEO8B.jpg (Wrong result)
But instead what I wanted to to obtain is this:
http://i.stack.imgur.com/R7Zhb.jpg
Is it possible?
Could you tell me if the way to proceed is correct?
Thanks!!
I have not enough reputation to post images and more than two links.
Sorry for my poor english.
So what you have is close, but you need to set the size of the container view to the content size of the table view once it has loaded its data. Your other views around the content view then need to respond to the change in size so you don't get overlaps.
If you know the height of each row in the table and how many there are then it's easiest to calculate the hight required and set that as the size of the content view. If you don't, or the height can change based on user choices or something like that, then you will need to do something more complicated which observes the content size of the table view and updates things when it changes.

Automatically adjusting UITableView height to display only the UITableViewCell(s) present

It seems that UITableView does not auto-calculate the exact height needed to cover all the visible cells, instead, it substitutes any extra area with empty rows.
I'd like to calculate the exact height needed to cover only the visible cells, as to rid my UITableView of those ugly empty rows. I am quite aware that this can be done manually using the Interface Builder, however there must be a more efficient and dynamic approach to this problem.
You can use the table view's content size to determine how much space the table wants.
CGFloat height = myTableView.contentSize.height;
This height will automatically consider headers, footers, and the size and number of cells, and pretty much anything else. And it's all dynamic, so if you decide to go to a 7 row table in the future, it will still work without a problem and without needing to change that piece of code. The only time you would need to change it is if you decided at some point that you no longer want to show the whole table anymore.
And a quick tip - you'll probably want to also set [myTableView setScrollEnabled:NO]. Disabling scrolling will prevent the table from "bouncing" if the user does try to scroll it - I just think that bouncing looks really silly if all the content of the table is being shown at once.
You can then use this height to either
adjust the constraints on your table view (if you are using Autolayout)
adjust the frame of your table view (if you use the old springs-and-struts approach)
Use the following code to get set cellHeight member variable and use it where ever required.
_cellHeight = floorf((CGRectGetHeight(self.tableView.bounds))/5);
This should give you height of each row and it will handle all cases.
The above code has to be used in following methods.
-(void)viewWillLayoutSubviews;
- (void)viewWillAppear:(BOOL)animated;
I hope this helps.

How can I change UITableView height to its content height and still have clickable content?

So I have a tableview where I changed the size to match its content size with this code.
CGRect testF = table1.frame;
testF.size.height = table1.contentSize.height;
table1.frame = testF;
But when I try to click any of the items I can only click the top two or the section in the red, because that is the initial height of the table in the beginning.
Is there a way around this, to dynamically change its height and still keep it clickable?
I would think that the problem is not that you re sized the tableview, but that there is something that is blocking those touch events. Perhaps you have some other view in the way or the tableview is nested inside of another view which has a frame set to the tappable area that you see but has clips to bounds off so you are able to see the tableview outside of it. Try doing something like the following and see if it works, this should test my theory out:
table1.superview.frame = cgrectMake(table1.superview.frame.origin.x, table1.superview.frame.origin.y, testF.size.width, testF.size.height);
Add this under the code you showed above.

UIScrollView with pagination + showing part of the previous/following pages

I'm trying to create a kind of a "game mode" menu similar to the one used by the "Cut the Rope" game to select the level pack:
What I want in particular is to achieve the same effect of showing the "current item" (in this case, the "2. Fabric Box" item) plus a bit of the previous and following items (to make sure the user is aware that there are more modes available by scrolling), with pagination enabled (to make the scroll view automatically "center" on these items).
This seems like a natural job for a UIScrollView with pagination enabled, however from the documentation it seems the pagination occurs on multiples of the view bounds.
So: if pagination occurs on multiples of the view bounds, is there any way to achieve this effect with a UIScrollView?
The fact that we see the full width of the screen would suggest that the UIScrollView frame's width would be 320px in this case, but each individual item would need to be smaller than that in order to show that little bit of the previous and next items, thus messing up the pagination...
For your reference, you can see a sample implementation of a page control from here.
https://developer.apple.com/library/content/samplecode/PageControl/Introduction/Intro.html
For the implementation you want,
to your surprise, the scrollview's width is actually smaller than 320 (or 480). The magic property to set is:
scrollView.clipsToBounds = NO
The only problem with this implementation is that the scrollview get no touch events if the touch is outside the bounds of the scrollView. This can be fix by passing its parent hitTest event to scrollView.
Just to link to to a better explanation:
UIScrollView horizontal paging like Mobile Safari tabs
Slightly different from what I recommend but does the same thing.
Edit:
I have a small project called LXPagingViews that does the above, hopefully in an out of the box manner (Do drop me a pull request or feedback in issue): https://github.com/lxcid/LXPagingViews

Resources