I want to add three views to a scrollview. These views have to be next to one another like Snapchat. However, when I launch my app on another device which is another size, the views don't adapt. Does someone know how can I resolve this problem?
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let MainEuroView = storyboard.instantiateViewController(withIdentifier: "MainViewController") as! MainViewController
let TicketEuroView = storyboard.instantiateViewController(withIdentifier: "TicketViewController") as! TicketViewController
let ProfilView = storyboard.instantiateViewController(withIdentifier: "ProfilViewController") as! ProfilViewController
var TicketViewFrame : CGRect = TicketView.view.frame
TicketViewFrame.origin.x = 0
TicketView.view.frame.size = CGSize(width: self.view.frame.width, height: self.view.frame.size.height)
TicketView.view.frame = TicketViewFrame
var MainViewFrame : CGRect = MainView.view.frame
MainViewFrame.origin.x = self.view.frame.width
MainView.view.frame = MainViewFrame
var ProfilViewFrame : CGRect = ProfilView.view.frame
ProfilViewFrame.origin.x = 2 * self.view.frame.width
ProfilView.view.frame = ProfilViewFrame
self.addChildViewController(TicketView)
self.main_Scroll_View.addSubview(TicketView.view)
TicketView.didMove(toParentViewController: self)
self.addChildViewController(MainView)
self.main_Scroll_View.addSubview(MainView.view)
MainView.didMove(toParentViewController: self)
self.addChildViewController(ProfilView)
self.main_Scroll_View.addSubview(ProfilView.view)
ProfilView.didMove(toParentViewController: self)
self.main_Scroll_View.contentSize = CGSize(width: self.view.frame.width * 3, height: self.view.frame.size.height)
A quick fix would be to move the frame adjustment to viewDidLayoutSubviews method, you usually don't have the view frame during viewDidLoad, but instead get the frame of the view in the storyboard, e.g.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
var TicketViewFrame : CGRect = TicketView.view.frame
TicketViewFrame.origin.x = 0
TicketView.view.frame.size = CGSize(width: self.view.frame.width, height: self.view.frame.size.height)
TicketView.view.frame = TicketViewFrame
var MainViewFrame : CGRect = MainView.view.frame
MainViewFrame.origin.x = self.view.frame.width
MainView.view.frame = MainViewFrame
var ProfilViewFrame : CGRect = ProfilView.view.frame
ProfilViewFrame.origin.x = 2 * self.view.frame.width
ProfilView.view.frame = ProfilViewFrame
}
A better fix would be to implement autolayout which will do this automatically for you.
Related
I'm trying to make a view container with table view. That's works fine, but if i select the last row, the method didSelectRowAt indexPath: cannot be triggered. This is my code:
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let controller = storyboard.instantiateViewController(withIdentifier: "pageViewController") as! PageViewController
addChildViewController(controller)
controller.customDelegate = self
controller.index = index
self.controller = controller
//Add Controllers
let clientInfoVC = storyboard.instantiateViewController(withIdentifier: "ClientInfo") as! ClientInfoViewController
clientInfoVC.client = self.client
let clientRequestsVC = storyboard.instantiateViewController(withIdentifier: "ClientRequests") as! ClientProductRequestViewController
clientRequestsVC.client = self.client
let clientDebtsVC = storyboard.instantiateViewController(withIdentifier: "ClientDebts") as! ClientDebtViewController
clientDebtsVC.client = self.client
controller.orderedViewControllers = [clientInfoVC,clientRequestsVC,clientDebtsVC]
controller.view.frame = CGRect(x: 0, y: 0, width: self.clientContainerView.frame.width, height: self.clientContainerView.frame.height)
self.clientContainerView.addSubview(controller.view)
controller.didMove(toParentViewController: self)
And this is my container view:
What am I doing wrong?
Please help me
I found the solution:
I needed to remove the controller's frame setting and thats it. So Just remove this line:
controller.view.frame = CGRect(x: 0, y: 0, width: self.clientContainerView.frame.width,
height: self.clientContainerView.frame.height)
I am having baseview controller with scrollview.In that scrollview I adding three viewcontrollers view(xib).So i can scroll those three in horizantal.In my first view controller I am displaying a tablevieew.While running my app,Its displaying all my 3 view controllers.But When I touch my tableview cell are disappeared.Same I have did in xcode 7.3.It was working fine.But in xcode 8 its not working.Please help me to solve this.I have attached my sample code
let scrollViewWidth:CGFloat = self.scrollContainer.frame.width
let scrollViewHeight:CGFloat = self.scrollContainer.frame.height
let x = CGFloat(i) * scrollViewWidth
if i == 0{
let qualification = EducationViewController (nibName: "EducationViewController", bundle: nil)
//qualification.view.frame.size.height = scrollViewHeight
//qualification.view.frame.size.width = scrollViewWidth
qualification.view.frame.origin.x = x
self.scrollContainer!.addSubview(qualification.view)
qualification.didMove(toParentViewController: self)
}
else if i == 1{
let state = StateRegistrationViewController (nibName: "StateRegistrationViewController", bundle: nil)
//state.view.frame.size.height = scrollViewHeight
// state.view.frame.size.width = scrollViewWidth
state.view.frame.origin.x = x
self.scrollContainer!.addSubview(state.view)
state.view.backgroundColor = UIColor.red
state.didMove(toParentViewController: self)
}
else if i == 2{
let exp = ExperienceViewController (nibName: "ExperienceViewController", bundle: nil)
// exp.view.frame.size.height = scrollViewHeight
// exp.view.frame.size.width = scrollViewWidth
exp.view.frame.origin.x = x
self.scrollContainer!.addSubview(exp.view)
exp.view.backgroundColor = UIColor.orange
exp.didMove(toParentViewController: self)
}}
Initiate the viewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let aViewController = storyboard.instantiateViewController(withIdentifier: "A") as! AViewController;
let bViewController = storyboard.instantiateViewController(withIdentifier: "B") as! BViewController;
let cViewController = storyboard.instantiateViewController(withIdentifier: "C") as! CViewController;
Add the viewControllers into an array
let viewControllers = [aViewController, bViewController, cViewController]
Run the for loop which adds the viewControllers to the scrollView
var idx:Int = 0
for viewController in viewControllers {
addChildViewController(viewController);
let originX:CGFloat = CGFloat(idx) * width;
viewController.view.frame = CGRect(x: originX, y: 0, width: width, height: height);
scrollView!.addSubview(viewController.view)
viewController.didMove(toParentViewController: self)
idx += 1;
}
All Done!
while adding the view of your custom viewcontroller on scrollview you should also add your custom viewcontroller as child controller of the main controller.
like in your case you have three custom controllers then as per the if else clause in your code you must add:
self.addChildViewController(qualification)
self.addChildViewController(state)
self.addChildViewController(exp)
in there respective blocks in your code.
Your code will be like:
let scrollViewWidth:CGFloat = self.scrollContainer.frame.width
let scrollViewHeight:CGFloat = self.scrollContainer.frame.height
let x = CGFloat(i) * scrollViewWidth
if i == 0{
let qualification = EducationViewController (nibName: "EducationViewController", bundle: nil)
//qualification.view.frame.size.height = scrollViewHeight
//qualification.view.frame.size.width = scrollViewWidth
qualification.view.frame.origin.x = x
self.scrollContainer!.addSubview(qualification.view)
self.addChildViewController(qualification)
qualification.didMove(toParentViewController: self)
}
else if i == 1{
let state = StateRegistrationViewController (nibName: "StateRegistrationViewController", bundle: nil)
//state.view.frame.size.height = scrollViewHeight
// state.view.frame.size.width = scrollViewWidth
state.view.frame.origin.x = x
self.scrollContainer!.addSubview(state.view)
self.addChildViewController(state)
state.view.backgroundColor = UIColor.red
state.didMove(toParentViewController: self)
}
else if i == 2{
let exp = ExperienceViewController (nibName: "ExperienceViewController", bundle: nil)
// exp.view.frame.size.height = scrollViewHeight
// exp.view.frame.size.width = scrollViewWidth
exp.view.frame.origin.x = x
self.scrollContainer!.addSubview(exp.view)
self.addChildViewController(exp)
exp.view.backgroundColor = UIColor.orange
exp.didMove(toParentViewController: self)
}}
I'm trying to present a popover from a UIMenuItem which anchor point is the rect of a selected text in a textView. I have the following code:
func pickColor(sender: UIMenuItem) {
let range = noteTextView.selectedTextRange
let beginningOfSelection = noteTextView.caretRect(for: (range?.start)!)
let endOfSelection = noteTextView.caretRect(for: (range?.end)!)
let storyboard: UIStoryboard = UIStoryboard(name: "ColorPicker", bundle: nil)
let colorVC = storyboard.instantiateViewController(withIdentifier: "ColorPickerViewController") as UIViewController
colorVC.modalPresentationStyle = .popover
let popover: UIPopoverPresentationController = colorVC.popoverPresentationController!
popover.sourceView = noteTextView
popover.sourceRect = CGRect(x: (beginningOfSelection.origin.x + endOfSelection.origin.x)/2, y: (beginningOfSelection.origin.y + beginningOfSelection.size.height)/2, width: 0, height: 0)
present(colorVC, animated: true, completion: nil)
}
The app crashes in the line colorVC.modalPresentationStyle = .popover. Can someone tell me what's going on here? Thanks! :)
I am trying to make a page control associated with an image array. I had it setup correctly just changing the background color and load in the initial image, but when I scroll nothing further is shown. Here is my code:
var images: [UIImage] = [
UIImage(named: "slide1.png")!,
UIImage(named: "loginButton.png")!,
UIImage(named: "slide1.png")!,
UIImage(named: "slide1.png")!
]
func setPageViewinScroll() {
for index in 0..<4 {
frame.origin.x = self.scrollView.frame.size.width * CGFloat(index)
frame.size = self.scrollView.frame.size
self.scrollView.pagingEnabled = true
self.imageView.image = images[index]
let subview = UIView(frame: frame)
self.scrollView.addSubview(subview)
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * 4, self.scrollView.frame.size.height)
pageControl.addTarget(self, action: Selector("changePage:"), forControlEvents: UIControlEvents.ValueChanged)
}
func changePage(sender: AnyObject) -> () {
let x = CGFloat(pageControl.currentPage) * scrollView.frame.size.width
scrollView.setContentOffset(CGPointMake(x, 0), animated: true)
}
Does anyone know where I am going wrong here?
How about adding your UIImageview to UIScrollview instead of UIView like this code?
var imageOne:UIImageView!
var imageTwo:UIImageView!
var imageThree:UIImageView!
var imageFour:UIImageView!
func functionCalledFromViewDidLoad() {
scrollView.frame = CGRectMake(0, 0, self.view.frame.width,self.view.frame.height)
let scrollViewWidth = scrollView.frame.width
let scrollViewHeight = scrollView.frame.height
imageOne = UIImageView(frame: CGRectMake(0, 0,scrollViewWidth, scrollViewHeight))
imageTwo = UIImageView(frame: CGRectMake(scrollViewWidth*1, 0,scrollViewWidth, scrollViewHeight))
imageThree = UIImageView(frame: CGRectMake(scrollViewWidth*2, 0,scrollViewWidth, scrollViewHeight))
imageFour = UIImageView(frame: CGRectMake(scrollViewWidth*3, 0,scrollViewWidth, scrollViewHeight))
scrollView.addSubview(imageOne)
scrollView.addSubview(imageTwo)
scrollView.addSubview(imageThree)
scrollView.addSubview(imageFour)
}
override func viewDidLayoutSubviews() {
scrollView.contentSize = CGSizeMake(scrollView.frame.width * 4, scrollView.frame.height)
imageOne.frame.size.height = scrollView.frame.height
imageTwo.frame.size.height = scrollView.frame.height
imageThree.frame.size.height = scrollView.frame.height
imageFour.frame.size.height = scrollView.frame.height
}
You also seem to need to add this code.
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
// Test the offset and calculate the current page after scrolling ends
let pageWidth:CGFloat = CGRectGetWidth(scrollView.frame)
let currentPage = Int(floor((scrollView.contentOffset.x-pageWidth/2)/pageWidth)+1)
// Change the page indicator
self.pageControl.currentPage = Int(currentPage)
}
There is a very good tutorial related to this topic, here
You are setting the image on the imageView and not on the subView. I.o.w. You are adding the subview to each page, but not setting the image on it.
Change the subview code to the following
let subview = UIImageView(frame: frame)
subview.image = images[index]
self.scrollView.addSubview(subview)
I'm trying to make a swipe navigation with view controllers instead of xib files using this tutorial : https://www.youtube.com/watch?v=3jAlg5BnYUU
I've managed to replace the xib files with view controllers but when I run the app the width of the view controllers is smaller than normal :
I don't understand as it is set identically as with the xib files. Anyone knows how to solve this?
Here is my code :
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
let vc0 = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController0")
self.addChildViewController(vc0!)
self.scrollView.addSubview(vc0!.view)
vc0!.didMoveToParentViewController(self)
let vc1 = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController1")
var frame1 = vc1!.view.frame
frame1.origin.x = self.view.frame.size.width
vc1!.view.frame = frame1
self.addChildViewController(vc1!)
self.scrollView.addSubview(vc1!.view)
vc1!.didMoveToParentViewController(self)
let vc2 = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController2")
var frame2 = vc2!.view.frame
frame2.origin.x = self.view.frame.size.width * 2
vc2!.view.frame = frame2
self.addChildViewController(vc2!)
self.scrollView.addSubview(vc2!.view)
vc2!.didMoveToParentViewController(self)
let vc3 = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController3")
var frame3 = vc3!.view.frame
frame3.origin.x = self.view.frame.size.width * 3
vc3!.view.frame = frame3
self.addChildViewController(vc3!)
self.scrollView.addSubview(vc3!.view)
vc3!.didMoveToParentViewController(self)
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width * 4, self.view.frame.size.height - 66)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Notice that using viewDidLoad for set frame manually is a bit risky and should be avoided since the bounds are not set. Instead use the viewDidLayoutSubviews to do that but take a look because the method is called all the time when the UI elements change including constraints.
var scrollViewAdded = false
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if !scrollViewAdded {
self.loadSrollView()
self.scrollViewAdded = true
}
}
func loadSrollView() {
self.scrollView.pagingEnabled = true
let vc0 = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController0")
self.addChildViewController(vc0!)
self.scrollView.addSubview(vc0!.view)
vc0!.didMoveToParentViewController(self)
let vc1 = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController1")
var frame1 = vc1!.view.frame
frame1.origin.x = self.view.frame.size.width
vc1!.view.frame = frame1
self.addChildViewController(vc1!)
self.scrollView.addSubview(vc1!.view)
vc1!.didMoveToParentViewController(self)
let vc2 = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController2")
var frame2 = vc2!.view.frame
frame2.origin.x = self.view.frame.size.width * 2
vc2!.view.frame = frame2
self.addChildViewController(vc2!)
self.scrollView.addSubview(vc2!.view)
vc2!.didMoveToParentViewController(self)
let vc3 = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController3")
var frame3 = vc3!.view.frame
frame3.origin.x = self.view.frame.size.width * 3
vc3!.view.frame = frame3
self.addChildViewController(vc3!)
self.scrollView.addSubview(vc3!.view)
vc3!.didMoveToParentViewController(self)
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width * 4, self.view.frame.size.height - 66)
}