contentsize and contentOffset equivalent in NSScroll view - ios

I am porting an app from Ipad to mac. (I know that it sounds weird)
I stuck with NSScrollview. Please guide me contentsize , contentOffset equivalent in NSScrollview.

UIScrollView* uiScroll;
uiScroll.contentSize;
uiScroll.contentOffset;
uiScroll.contentSize = CGSizeMake(w,h);
uiScroll.contentOffset = CGPointMake(x,y);
=
NSScrollView* nsScroll;
nsScroll.documentView.frame.size;
nsScroll.documentVisibleRect.origin;
nsScroll.documentView.frameSize = NSMakeSize(w,h);
[nsScroll.documentView scrollPoint:NSMakePoint(x,y)];
Or perhaps even better:
import AppKit
extension NSScrollView {
var documentSize: NSSize {
set { documentView?.setFrameSize(newValue) }
get { documentView?.frame.size ?? NSSize.zero }
}
var documentOffset: NSPoint {
set { documentView?.scroll(newValue) }
get { documentVisibleRect.origin }
}
}
Notes: I used 'documentSize' (and 'documentOffset') because 'contentSize' conflicts with an already existing property of NSScrollView.

In addition to the lines from #aepryus, here are a couple more useful lines for getting/setting the scroll offset on macOS:
//Get the current scroll offset:
_contentViewOffset = scrollView.contentView.bounds.origin;
//Set the scroll offset from the retrieved point:
NSPoint scrollPoint = [scrollView.contentView convertPoint:_contentViewOffset toView:scrollView.documentView];
[scrollView.documentView scrollPoint:scrollPoint];

Everything you need to know about NSScrollView is laid out in the Scroll View Programming Guide for Cocoa provided in the documentation.
Although it doesn't appear that there's a direct equivalent, UIScrollView's contentSize can be likened to the size of NSScrollView's documentView, which is the scrollable content provided as an NSView to NSScrollView with setDocumentView:.
setContentOffset: can be compared to NSView's scrollPoint:, which uses an NSPoint to specify the offset of the documentView within the NSScrollView.
See the documentation for elaboration and code examples.

Related

How to dynamically size UIScrollView?

I'm adding content to the UIScrollView dynamically. The content size of the scroll view is increasing. How can I change the content size to fit the dynamically added content? See the code I'm using that is not working
extension UIScrollView {
func updateContentView() {
contentSize.height = subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? contentSize.height
contentSize.height += 300
}
}
refer this question
I hope the above solves your problem but I'd prefer using a UITableView or a UICollectionView in place of this because everything is handled so smoothly in them. You just have to give the number of rows(return a variable which changes dynamically). That's it, your contentSize is adjusted internally.
But again if you have a different requirement please go with the reference link!

Zoom in/out on swiping tableView Animation

I want to achieve this animation:
Here is the Gif: http://imgur.com/4TZIbwp
Since the content is dynamic, I'm using tableView to populate the data.
I've tried scrollViewDidScroll delegate methods to change the constraints but it's not helping me. I've even tried swipe gesture, but still can't manage to achieve this.
Can anyone provide a knowledge, a bit of code for getting this animation.
I have tried to tackle your issue in this project.
The flaw with this solution is that it requires an unattractive inset at the top of the table view to translate the offset into a meaningful variable with which to shrink the table view.
The relevant code in the project is within the scroll delegate function:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let yOffset = min(0.0, max(-maximumOffset, scrollView.contentOffset.y))
let constant = -yOffset
topTableViewConstraint.constant = constant
leadingTableViewConstraint.constant = constant / 5.0
trailingTableViewConstraint.constant = constant / 5.0
view.layoutIfNeeded()
}
I am sorry that I cannot be more helpful, or provide you with a final solution.
Hopefully the project will aid you in find that answer.

Why does sizeThatFits() return a size that is too small?

I'm learning swift with cs193p and I have a problem with UITextView.sizeThatFits(...). It should return a recommended size for popover view to display an [int] array as a text. As you can see in Paul Hegarty's example (https://youtu.be/gjl2gc70YHM?t=1h43m17s), he gets perfectly-fit popover window without scrollbar. I'm using almost the same code that was in this lecture, but instead i've got this:
the text string equals [100], but the sizeThatFits() method is returning a size that is too small to display it nicely, even though there is plenty of free space.
It is getting a bit better after I've added some text, but still not precise and with the scrollbar:
Here is the part of the code where the size is being set:
override var preferredContentSize: CGSize {
get {
if textView != nil && presentingViewController != nil {
// I've added these outputs so I can see the exact numbers to try to understand how this works
print("presentingViewController!.view.bounds.size = \(presentingViewController!.view.bounds.size)")
print("sizeThatFits = \(textView.sizeThatFits(presentingViewController!.view.bounds.size))")
return textView.sizeThatFits(presentingViewController!.view.bounds.size)
} else { return super.preferredContentSize }
}
set { super.preferredContentSize = newValue }
}
What should I do so this will work in the same way as in the lecture?
It looks like there are 16 pt margins between the label and its parent view. You need to take that into account when returning the preferred size of the popover.
You should try both of the following:
Add 32 to the width that's returned from preferredContentSize
In Interface Builder, clear the layout constraints on your UILabel, then re-add top, bottom, leading, and trailing constraints and make sure that "Constrain to Margins" option is not enabled.
Finally, instead of overriding preferredContentSize, you can simply set the preferredContentSize when your view is ready to display, and you can ask Auto Layout to choose the best size:
override func viewDidLayoutSubviews() {
self.preferredContentSize = self.view.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
}
If your layout is configured correctly, systemLayoutSizeFitting(UILayoutFittingCompressedSize) will return the smallest possible size for your view, taking into account all of the margins and sub-views.

Set NSLayoutConstraint Constant in iOS7

Ok, I have a super weird issue. I have a UIScrollView that I'm using to update the position of a second UIView. So, when you scroll the UIScrollView, the UIView moves as well at a proportional but slower speed. The code is pretty simple.
Scroller.Scrolled += delegate {
if (Scroller.ContentOffset.Y <= 0) {
filtersTop.Constant = 0;
} else {
filtersTop.Constant = -(Scroller.ContentOffset.Y / 2);
}
}
filtersTop is a NSLayoutConstraint. Scroller is the UIScrollView.
The problem is whenever I set filtersTop.Constant to any value derived from Scroller.Content.Y, it resets Scroll.ContentOffset to 0 in iOS7 only. This code works fine in iOS8+. I've tried a dozen variations on this. If I set filtersTop.Constant to a static number (ie: 123.5), that works.
I've tried saving the value to a variable and forcing the type thinking maybe it was getting cast improperly. If I trace out the value, it works. But, the minute I set it to filtersTop.Constant, it resets Scroller.ConstentOffset.Y again. Scroller and filters are NOT related. They are not nested or associated with each other in any way. So, I have no idea why setting the constant on the constraint on filters would in any way affect Scroller.
Anyone know what is happening here?
Ok I had another look it seems to be resetting the contentSize between calling ViewWillLayoutSubviews and calling ViewDidLayoutSubviews
ContentSize set to: {Width=320, Height=3000}
Called ViewWillLayoutSubviews
ContentSize set to: {Width=320, Height=3000}
ContentSize set to: {Width=0, Height=0}
Called ViewDidLayoutSubviews
I then subclassed the scrollview and forced the contentSize to stay the same like so:
public class CustomScroller : UIScrollView
{
public CustomScroller ()
{
ContentSize = new CGSize(320,3000);
}
public override CGSize ContentSize {
get {
return base.ContentSize;//new CGSize(320,3000);
}
set {
base.ContentSize = new CGSize(320,3000);
Console.WriteLine ("ContentSize set to: "+ContentSize);
}
}
public override void LayoutSubviews ()
{
Console.WriteLine ("LayoutSubviews: "+Frame.Y);
base.LayoutSubviews ();
}
}
You will then have to set the contentSize when the view loads rather than in ViewDidLayoutSubviews.
I have updated the code here with the solution detailed above and here is the result.
Note I changed the scrolled code but it will work with the original too.
This works in iOS7 and iOS8. Hope this helps!

UIPageController currentPage stubbornly sets itself to nib value

I have a UIPageController that I placed in my xib file, so I could get the placement proper, but the value of "currentPage" set in the xib is the value that currentPage assumes when i try to set it to something else, like below, the line of code that sets my UIScrollView to the proper initial image when starting in the middle (i.e. not page 0):
aScrollView.contentOffset = CGPointMake((currentIndex + 0.0) * screenWidth, 0.0);
which calls
-(void) scrollViewDidScroll: (UIScrollView*) aScrollView
{
// Update the page control to match the current scroll:
CGPoint offset = aScrollView.contentOffset;
float width = self.view.frame.size.width;
int pageNumber = (int)(offset.x / width);
uiPageControl.currentPage = pageNumber;
NSLog(#"%g // %g = %d", offset.x, width, (int)(offset.x/width));
}
The pageNumber integer is correct, so I am properly calculating the desired page number from the offset. However, when I try to manually (programatically) set currentPage, it doesn't set to pageNumber, it sets to the value in the xib.
Easy solution is to not use the xib and do it all programatically, but I want to know how I can continue using the UIPageController in the xib, because it was easy to place without knowledge of coordinates, etc. Normally, Attributes set in the xib are overwritable programatically, so this bug really surprised me. Any suggestions on how I can properly set currentPage?
Thanks for your help!
I found a hack that temporarily solves my problem: in the xib, I set the "Number of Pages" value to something I know will be higher than the number of pages I will ever have.
If this is too small, it turns out that setting currentPage beyond that value didn't do anything because it was clamping or setting it to some number below the number of pages I had in the xib.
If I set this xib attribute higher, then setting currentPage works.
Sorry for the quick trigger.

Resources