How to move UIPageViewController's PageController buttons position in the View - ios

I have implemented Page Swipe with a UIPageViewController.
Delegates and DataSource are working properly. The indexing, the whole thing.
The problem I have is, since the Page Controller is part of the UIPageViewController, its default position is at the bottom. Since it is part of it, I can not change it on the storyboard.
Could anyone point me in the right direction?
I tried this, but didn't work
self.view.frame = CGRect(origin: CGPoint(x: 0.0, y: 30.0), size: CGSize(width: self.view.frame.width, height: self.view.frame.size.height - 200.0))
Also tried this.
But all it did was create a second PageControl
let pageControl = UIPageControl()
pageControl.pageIndicatorTintColor = UIColor.grayColor()
pageControl.currentPageIndicatorTintColor = UIColor.whiteColor()
pageControl.backgroundColor = UIColor.darkGrayColor()
pageControl.numberOfPages = 4
pageControl.center = self.view.center
self.view.addSubview(pageControl)
pageControl.layer.position.y = self.view.frame.height - 200;
// 200 point from bottom of the screen
I have googled it, but didn't find anything useful.
Thanks

There are two possible solutions:
Update current UIPageControl's position in UIPageViewController's viewDidLayoutSubviews like it's shown here
Create your own UIPageControl and do not use the default one
Personally, I don't like hacking system controls, so I'd prefer to create a new one and customize it as I want.
Good luck!

Related

How to do UITextView scroll detect and change images

It looks like this :
(I can't show image please I don't have 10 prestiges)
let departmentMessage = UITextView(frame: CGRect(x: 25, y: 1500 / 2, width: UIScreen.main.bounds.size.width - 50, height: (UIScreen.main.bounds.size.height - 50)/4 ))
showBlshText()
departmentMessage.isScrollEnabled = true
departmentMessage.isPagingEnabled = true
departmentMessage.isEditable = false
departmentMessage.isSelectable = true
departmentMessage.dataDetectorTypes = UIDataDetectorTypes.link
departmentMessage.textColor = UIColor.darkGray
departmentMessage.textAlignment = .left
departmentMessage.contentMode = .topLeft
departmentMessage.backgroundColor = UIColor(displayP3Red: 100, green: 100, blue: 100, alpha: 20)
departmentMessage.font = UIFont(name: "Helvetica-Light", size: 20)
self.view.addSubview(departmentMessage)
departmentMessage.removeFromSuperview()
I expect the output of the word to change, but the actual output isn't work.
UITextView is a subclass of UIScrollView. So everything that a scrollView does a textView can do also. In you case, it seems that you want to do some action when the textView is scrolled. You should look the UIScrollViewDelegate documentation which describes how you can monitor a scrollView to see when it is scrolled. There are a few tips to know:
the delegate is not called when you set the content offset programatically.
scrollViewDidEndDecelerating: is not called when scrollViewDidEndDragging:willDecelerate: is called with NO for the willDecelerate value.
So just set your viewController as the delegate, implement the appropriate methods, and change your UI accordingly.
Also, you might have better luck using a UICollectionView or a UITableView. Even if every row is just a label, it is far easier to track what indexPath is at the top of the collectionView then what text is at the top of textView. But without knowing exactly what you are doing it is hard to say.

Can I insert a scrollview before a view in IOS?

The answer can be for swift, objective-c or c# even if I'm using xamarin.
I have issues creating scrollview in the storyboard with xamarin, I followed several tutorial for xcode but I can't do what I need.
Then I removed the scrollview and just have a long vertical uiview and actualy added some code to scroll it using pangesture moving the uiview frame.
But I know it would be better to use srollview also I though that it must be possible to insert a scrollview before the view (in code) to achieve the same thing.
So is it possible ?
Yes it is possible, for example you could do this in your ViewController by adding the ScrollView as a subview to your View.
override func viewDidLoad() {
super.viewDidLoad()
let scrollViewFrame = view.bounds
let scrollView = UIScrollView(frame: scrollViewFrame)
scrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
scrollView.backgroundColor = UIColor.red
view.addSubview(scrollView)
let innerView = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
innerView.backgroundColor = UIColor.blue
scrollView.addSubview(innerView)
scrollView.contentSize = CGSize(width: scrollViewFrame.width, height: scrollViewFrame.height * 2)
}
In this example the ScrollView has the same size as the main View. You can adjust this by changing the scrollViewFrame constant.
The innerView has a fixed size of 50x50. If it should cover the entire scrollView, just use the scrollViewFrame and the same autoresizingMask.
I adjusted the contentSize to be twice as high as the scrollView in order to make it scroll. This might or might not be necessary for your solution.

Reproducing Music App's NavigationBar Animation

In my project I want to achieve a very similar animation like in the Artist-ViewController of the stock Music App.
When the UITableView scrolls to a specific offset the navigationBar's tintColor, the color of the title and the color of the statusbar changes.
To achieve that I added an UIView (I named it containerView) as a subView of the UINavigationBar and inside that containerView I added a UIBlurEffect. Now when the tableView scrolls I am listening to scrollViewDidScroll to change the earlier named attributes which works really good.
containerView.frame = CGRect(x: 0, y: -(statusBarHeight), width: UIScreen.main.bounds.width, height: frame.height + statusBarHeight)
containerView.clipsToBounds = true
insertSubview(containerView, at: 0)
let blurEffect = UIBlurEffect(style: .extraLight)
overlayView.effect = blurEffect
overlayView.backgroundColor = unOverlayColor
let height = frame.height + statusBarHeight
overlayView.frame = CGRect(x: 0, y: containerView.frame.height, width: containerView.frame.width, height: height)
containerView.addSubview(overlayView)
My only problem is that the containerView is placed above the UINavigationBar's navigationItems and therefore hides them.
So my question is how can I add the containerView behind the navigationItems to the UINavigationBar?
I figured out that it has to be something with the way how navigationBars are handled in iOS 11 because on iOS 10 everything works fine.

Why does my UITableViewFooter jump to the top?

self.tableView.tableFooterView = PromptInviteView.instantiateFromNib()
I've tried putting this in viewWillAppear and viewDidLoad.
Great, everything shows up and displays correctly.
However, if:
I push HOME and open 4-5 other apps, then return back to my app, the footer will "jump" to the top, covering the first row.
If I perform other actions inside the app (navigating back and forth), and then finally going back to his vc, then it will jump to the top also.
When I pull to refresh, all is good again. But if I don't do anything...the footer stays at the top (replacing the top row + is not clickable)
Does anyone know why this behavior is occurring, and how I can solve it?
Update: I realize that "drawRect" in my xib gets called when I open the app after 4-5 other apps. And this is why the problem is happening.
In my drawRect code, I have this:
override func drawRect(rect: CGRect) {
super.drawRect(rect)
inviteLabel.textColor = UIColor(hex: 0x404040)
inviteLabel.text = STRINGS["PromptInviteLabelText"]
inviteLabel.numberOfLines = 0
inviteLabel.sizeToFit()
inviteButton.setTitle(STRINGS["PromptInviteButtonText"], forState: UIControlState.Normal)
inviteButton.backgroundColor = FlatWatermelon()
inviteButton.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
inviteButton.setTitleColor(UIColor(hex: 0xcccccc), forState: UIControlState.Selected)
inviteButton.layer.cornerRadius = 2.0
inviteButton.clipsToBounds = true
super.layoutSubviews() //this will allow the view's frame to be set.
var padding = CGFloat(20.0)
self.frame = CGRectMake(0, 0, screenWidth, CGRectGetMaxY(inviteButton.frame) + padding )
var topBorder = UIView()
topBorder.frame = CGRectMake(0, 0, screenWidth, 0.5)
topBorder.backgroundColor = UIColor(hex: 0xededed)
self.addSubview(topBorder)
var bottomBorder = UIView()
bottomBorder.frame = CGRectMake(0, self.frame.size.height, screenWidth, 0.5)
bottomBorder.backgroundColor = UIColor(hex: 0xededed)
self.addSubview(bottomBorder)
}
How can I remove my code (especially the layoutSubview part) and put it somewhere else?
Is there another location where I should put the code? Is there a didLayoutSubviews() equivalent?

Twitter-like UIScrollView with ViewControllers as pages

Video of the issue!
Example of what I mean by Twitter-like UIScrollView:
I basically have it working, but I have this small glaring issue and I don't know where it is coming from. I have checked all the constraints and values for my two view controllers, but something is off.
In short,
The code that creates the NavBar and then populates it with the two ViewControllers side by side:
override func viewDidLoad() {
super.viewDidLoad()
var navBar: UINavigationBar = UINavigationBar(frame: CGRectMake(0, 0, self.view.bounds.width, 64))
navBar.barTintColor = UIColor.blackColor()
navBar.translucent = false
//Creating some shorthand for these values
var wBounds = self.view.bounds.width
var hBounds = self.view.bounds.height
// This houses all of the UIViews / content
scrollView = UIScrollView()
scrollView.backgroundColor = UIColor.clearColor()
scrollView.frame = self.view.frame
scrollView.pagingEnabled = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.delegate = self
scrollView.bounces = false
self.view.addSubview(scrollView)
self.scrollView.contentSize = CGSize(width: self.view.bounds.size.width * 2, height: hBounds)
//Putting a subview in the navigationbar to hold the titles and page dots
navbarView = UIView()
//Paging control is added to a subview in the uinavigationcontroller
pageControl = UIPageControl()
pageControl.frame = CGRect(x: 0, y: 35, width: 0, height: 0)
pageControl.pageIndicatorTintColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.3)
pageControl.currentPageIndicatorTintColor = UIColor.whiteColor()
pageControl.numberOfPages = 2
pageControl.currentPage = 0
self.navbarView.addSubview(pageControl)
//Titles for the nav controller (also added to a subview in the uinavigationcontroller)
//Setting size for the titles. FYI changing width will break the paging fades/movement
navTitleLabel1 = UILabel()
navTitleLabel1.frame = CGRect(x: 0, y: 8, width: wBounds, height: 20)
navTitleLabel1.textColor = UIColor.whiteColor()
navTitleLabel1.textAlignment = NSTextAlignment.Center
navTitleLabel1.text = "Title 1"
self.navbarView.addSubview(navTitleLabel1)
navTitleLabel2 = UILabel()
navTitleLabel2.alpha = 0.0
navTitleLabel2.frame = CGRect(x: 100, y: 8, width: wBounds, height: 20)
navTitleLabel2.textColor = UIColor.whiteColor()
navTitleLabel2.textAlignment = NSTextAlignment.Center
navTitleLabel2.text = "Title 2"
self.navbarView.addSubview(navTitleLabel2)
//Views for the scrolling view
//This is where the content of your views goes (or you can subclass these and add them to ScrollView)
feedViewController = storyboard?.instantiateViewControllerWithIdentifier("FeedController") as FeedViewController
view1 = feedViewController.view
addChildViewController(feedViewController)
feedViewController.didMoveToParentViewController(self)
view1.frame = CGRectMake(0, 0, wBounds, hBounds)
self.scrollView.addSubview(view1)
self.scrollView.bringSubviewToFront(view1)
//Notice the x position increases per number of views
secondViewController = storyboard?.instantiateViewControllerWithIdentifier("SecondController") as SecondViewController
view2 = secondViewController.view
addChildViewController(secondViewController)
secondViewController.didMoveToParentViewController(self)
view2.frame = CGRectMake(wBounds, 0, wBounds, hBounds)
self.scrollView.addSubview(view2)
self.scrollView.bringSubviewToFront(view2)
navBar.addSubview(navbarView)
self.view.addSubview(navBar)
}
I've looked at my storyboard and both ViewControllers seem identical in regards to their constraints.
I know this is an issue because both ViewControllers are populated by UITableViews. When I scroll through the SecondViewController, it works perfectly. When I scroll through the FeedViewController, there is a small white space at the top that I can't seem to get rid of and it shows that the text cuts off there. I've been stuck on this for a long time and if there is any other information needed, I'll gladly provide it.
Edit: Included video of the issue. If I could, I would bounty this question right now. I don't understand the cause
Update: After swapping both ViewController positions, I have noticed that the problem does not lie with either ViewController. The problem lies with page 1 being set lower. When swapped, the original SecondViewController also experienced the same behavior
So, I think everyone who implements this runs into this issue at some point. The issue isn't with the first ViewController. Simply adjust the constraint to be 44 from the top. The issue is with the second ViewController and it isn't so much an issue when you understand how they work. Technically, it is off to the side and hence its top constraint does not adhere to the Navigation Bar, so what you have is a constraint - 20. Which, depending on how you originally placed your constraints, can give you this seeming issue.
But basically, anyone and everyone will run into this issue when implementing this.
TL;DR: To make everything seamless, your second, third, fourth, fifth, etc. page View Controllers need a constraint + 20 of your first View Controller. With my set-up, I use a constraint of 44 for my first View Controller and hence 64 for the second

Resources