I have an app in Swift 4.0 in which I have a wide scrollview containing multiple images that are each as wide as the screen. Currently the user can swipe through them, which works perfectly. I'm in the process of adding buttons for paging left and right. The code for one of the buttons is below (the left button has the same structure).
When I use the buttons to page right or left, the content offset does not change at all. For example, if I start out on page #1, the horizontal content offset is 0. When I run the scrollRight function, the content offset remains 0, even though it's showing page #2 (it prints "content offset = 0"). If I swipe instead, it displays page #2, but the content offset updates to UIScreen.main.bounds.width (it prints "content offset = 414")
func scrollRight(){
let currentX = sectionScroll.contentOffset.x
let newX = currentX + UIScreen.main.bounds.width
sectionScroll.setContentOffset(CGPoint(x: newX, y: 0), animated: true)
print("content offset= ", sectionScroll.contentOffset.x)
}
What am I doing wrong? Do I just not understand how UIScrollViews function? Is there a way to use the button to display the next page and also update the content offset in the same way that scrolling would? I end up using the content offset in later code to determine which page the user is looking at, so I'd like it to be able to update whether the user swipes or clicks through the pages.
I found the solution in case anyone else runs into a similar issue.
When the animation is set to "true", it takes time to move to the new offset. Therefore, you have to take that into account-- I just built in a short delay before running the rest of my code, although I'm sure there are other ways around it.
Related
I have an app that uses ExtJS 3.3.0. It uses an EditorGridPanel in which after the store is reloaded - I would like it to preserve the scroll position of the grid rather than sending it back up to the top.
Because this is an earlier version of ExtJS - this DOES NOT work:
viewConfig: {
preserveScrollOnRefresh: true
}
So far the only thing I can come up with is to save the position of the scroll bar prior to loading - and then reset the position once the reload is complete.
I can get as far as saving the position:
var scrollPos;
bodyscroll: function(sl, st) {
scrollPos = st;
},
However I can't figure out how to set the position afterwards.
Any suggestions?
Thanks in advance.
There might be multiple ways to do this but one way is to use the scroller element, which is accessible through the grid's gridview. See fiddle here: Grid scoll save/restore.
To get scroll value (which you've already got figured out):
var top = grid.getView().scroller.getScroll().top;
To restore:
grid.getView().scroller.scrollTo('top',top);
I am making a program that repeatedly creates pages of an undefined quantity, and on the top of all the pages is a logo that is in a certain position. If I have everything in a for loop and at the end I include these commands to make a page break:
Set oRng = oDoc.Bookmarks("\EndOfDoc").Range
oRng.InsertBreak
The second time (and subsequent times) the table I make goes on the the next page, but the image does not. I have tried setting the "top" property to
distFromTop + pageLength * pageNumber.
I would assume it might have to do with the anchor property, but I have no idea what data type that even gets or how it affects the placement
I insert the image using:
oDoc.Shapes.AddPicture "C:\Users\name\Desktop\file.jpg", , , CentimetersToPoints(1.3), CentimetersToPoints(0.9 + pageLength * j), CentimetersToPoints(6.1), CentimetersToPoints(2.9)
The picture adds multiple times, but both to .9 from the top on the first page and 1.3 from the left, on the first page.
How can I make the pic go .9 from the top of a certain page
EDIT: I would like to avoid putting it in a header because that would mess up the alignment of the other elements of the doc
Ok, So what worked for me was this:
Set oRng = oDoc.Bookmarks("\EndOfDoc").Range
oRng.InsertBreak
oDoc.Shapes.AddPicture "C:\Users\me\Desktop\file.jpg", , , CentimetersToPoints(1.3),
CentimetersToPoints(0.9), CentimetersToPoints(6.1), CentimetersToPoints(2.9),
oDoc.Bookmarks("\EndOfDoc").Range
I still don't quite understand why it works, because the documentation for a range objects / anchors was fairly hard for me to understand... I tried this out and this worked. For my purposes that worked, but if anyone knows why that works I would love to know
Thanks for your answers
So I have a button on my storyboard. When that button is pressed, I want to move a certain label down a little bit and also add a new text field to the screen. Here is the simplified code:
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.addIngredientLabel.center.y += self.addIngredientLabel.bounds.height
}) { (_) -> Void in
let newIngredientTextField = UITextField(frame: CGRectMake(100, 110, 100, 100))
newIngredientTextField.center.y -= 50
newIngredientTextField.placeholder = "place text here"
newIngredientTextField.contentHorizontalAlignment = .Left
self.view.addSubview(newIngredientTextField)
}
The problem though, is that after the animation is completed, the label jumps back to its original location. It is like the animation is being pre-maturely terminated. The textField gets added and the label moves but it does not stay moved.
I have tried adding the text field at the end of the function instead of in a completion block. No kind of reordering seems to be helping.
I feel like I am not understanding something fundamental to animations. If anyone has any advice I would greatly appreciate it.
Since you're using the storyboard, you are most likely also using auto-layout. The positions of your controls are determined in your visual design (storyboard) and will adjust automatically to orientation changes and adapt to various device screen sizes. This is good but the flip size is that you cannot directly change the positions of your control using their x,y coordinates.
Instead, you can change values in the constraints you defined in the storyboard. for example, if you button has a "Top" distancs constraint with a control above it (or the edge of the view), you can change the constraint's "constant" attribute to indirectly change the position of the control.
In order to manipulate the contraints in your code, you can create IBOutlets for them just as you would do with any control.
I'm trying to work with a scroll view controller that needs to adjust it's contents based on user interaction -- specifically, by adding a 'done' button while the user is working with a UITextView, then removing it when they are done. The problem is making room for the button in question. What I'd like to do is...
control.layer.position.x-=50;
for every single control that is 'below' the one I'm working with. Unfortunately, that doesn't work. As far as I can tell, I'm going to have to do something more like...
control.layer.position=CGPointMake(newX, newY);
This creates a maintainability nightmare; instead of being able to rearrange buttons inside UIBuilder at will, I'm going to have to change their positions in the code as well. Unfortunately, no matter what variant of the first type of code I use, the result doesn't work; I'm informed that I need an lvalue to the left of the assign or that I'm trying to manipulate incompatible types.
It'll be more verbose than the -= solution, but why don't you just calculate newX and newY based on their old values?
e.g.
CGPoint oldPosition = control.layer.position;
control.layer.position = CGPointMake(oldPosition.x - 50, oldPosition.y);
The button comes with a center property, so:
button.center = CGPointMake(button.center.x - 50, button.center.y);
should do the trick
I'm using two UIPageControls in a view to reflect chapters and pages. So I have defined one UIPageControl named chapterCount and one named pageCount just to show where the user is. I handle the flipping of the pages with swipes rather than using the UIPageControls (so no methods defined for them).
I change their values as the user change pages with the following code:
chapterCount.numberOfPages = chapters;
chapterCount.currentPage = chapterNumber;
pageCount.numberOfPages = pages;
pageCount.currentPage = pageNumber;
[chapterCount updateCurrentPageDisplay];
[pageCount updateCurrentPageDisplay];
Where chapters, chapterNumber, pages and pageNumber all are integers.
The first time I flip through the pages it normally works fine, but when I go to a previous chapter or start a new chapter, the first (or last depending on direction) dot is not showed. Please see picture (upper half is missing a dot, lower one OK).
alt text http://img80.imageshack.us/img80/3339/pagecontrol.png
Its the same code updating the controls and sometime I get a dot, sometimes not. When I check the variables with NSLOG they are correct (eg the same for both pictures above).
I have checked Apple's documentation and tried their example but no luck.
Where should I start troubleshooting? I'm getting crazy!!
I finally found the problem :-)
An UIPageControl that is given a value 0 for number of pages will not show correctly the next time it is updated. I was reading chapter and page numbers from an array and in the beginning (let's say cover of the book) there are no pages and no chapters to show, so I happily set these to 0. Since I did not want to change the source data in my array I used MAX(pages , 1) for numberOfPages, so now it's working like clockwork.
Are you sure your chapterCount and pageCount views are not nil? You can have valid values all day, a message to nil does nothing and returns nil. Double check your view and controller wiring/unwiring when you change chapters.
EDIT:
confirm the size of the control is big enough to hold all your pages, and the view bounds is not clipped. For example, if you had 10 pages, and the "current" page was 10, but there were only 9 dots visible, it would appear as though nothing is highlighted because the white dot would be clipped from the visible area by being outside the viewable bounds. You can adjust the size dynamically using this:
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount