Adding viewcontrollers in scrollview ios swift - ios

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)
}}

Related

Display view on my scrollview

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.

How to present popover from tab bar item?

I want to present a ViewController as popover in Swift 4, but it presents the Viewcontroller normally, this is the code:
class CustomTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let favViewController = TrialViewController()
let exhibtionViewController = TrialViewController()
let menuViewController = ttttViewController()
let notificationViewController = TrialViewController()
let profileViewController = ttttViewController()
favViewController.tabBarItem.title = "first"
exhibtionViewController.tabBarItem.title = "second"
menuViewController.tabBarItem.title = "third"
notificationViewController.tabBarItem.title = "forth"
profileViewController.tabBarItem.title = "fifth"
favViewController.tabBarItem.image = UIImage(named:"home25")
exhibtionViewController.tabBarItem.image = UIImage(named: "bag25")
menuViewController.tabBarItem.image = UIImage(named: "main_add_25")
notificationViewController.tabBarItem.image = UIImage(named: "notification25")
profileViewController.tabBarItem.image = UIImage(named: "man_man25")
let tabBarItemWidth = Int(self.tabBar.frame.size.width) / (self.tabBar.items?.count)!
let x = tabBarItemWidth * 3;
let newRect = CGRect(x: x, y: 0, width: tabBarItemWidth, height: Int(self.tabBar.frame.size.height))
print(newRect)
menuViewController.modalPresentationStyle = .popover
menuViewController.view.frame = newRect
menuViewController.preferredContentSize = CGSize(width: 150,height: 150)
if let popoverMenuViewController = menuViewController.popoverPresentationController {
popoverMenuViewController.permittedArrowDirections = .down
popoverMenuViewController.delegate = menuViewController as? UIPopoverPresentationControllerDelegate
popoverMenuViewController.sourceRect = newRect
popoverMenuViewController.sourceView = self.tabBar
present(menuViewController, animated: true, completion: nil)
}
viewControllers = [favViewController, exhibtionViewController, menuViewController, notificationViewController, profileViewController]
}
}
what is the problem with my code?
override func viewDidAppear(_ animated: Bool) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "bbb") as! ttttViewController
vc.modalPresentationStyle = .popover //presentation style
vc.preferredContentSize = CGSize(width: 150,height: 150)
vc.popoverPresentationController?.delegate = self as! UIPopoverPresentationControllerDelegate
vc.popoverPresentationController?.sourceView = view
vc.popoverPresentationController?.sourceRect = self.tabBar.frame
self.present(vc, animated: true, completion: nil)
}
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
demo is here popover

Anchor a popover to the rect of a selected textRange in textView iOS

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! :)

How to change the ViewControllers frame position inside the PageViewController?

The Code I Have written for loading view controllers in Page View Controllers.
Programatically creating four view controllers and adding them to Page View Controller.
I have changed the view controllers frame position but still not changing in the app
let controller: UIViewController = UIViewController()
print(controller.view.frame)
controller.view.frame = CGRectMake(10, 20, self.view.frame.width/2, self.view.frame.height - 20)
print(controller.view.frame)
controller.view.backgroundColor = UIColor.blackColor()
let controller2: UIViewController = UIViewController()
controller2.view.backgroundColor = UIColor.redColor()
let controller3: UIViewController = UIViewController()
controller3.view.backgroundColor = UIColor.blackColor()
let controller4: UIViewController = UIViewController()
controller4.view.backgroundColor = UIColor.greenColor()
let p1 = controller
let p2 = controller2
let p3 = controller3
let p4 = controller4
myViewControllers = [p1,p2,p3,p4]
for index in 0 ..< myViewControllers.count {
NSLog("\(myViewControllers[index])")
}
let startingViewController = self.viewControllerAtIndex(0)
let viewControllers: NSArray = [startingViewController]
self.setViewControllers(viewControllers as? [UIViewController], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: {(done: Bool) in
})

Creating floating text box in ios application

I want to add an option when clicking on a cell it will show floating text box above the keyboard and its blurs the background.
Anyone familiar with this and how to implement it?
You can view image at the following link:
Start with adding some properties to your class:
var textField = UITextField()
var composeBarView = UIView()
var blurView = UIView()
let barHeight:CGFloat = 44
Next create the blur view, textField and container view. Do this in the viewWillAppear:
blurView = UIView(frame: self.view.frame)
blurView.alpha = 0.5
blurView.backgroundColor = UIColor.blackColor();
self.view.addSubview(blurView);
blurView.hidden = true;// Note its hidden!
textField = UITextField(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, barHeight))
composeBarView = UIView(frame: CGRectMake(0, UIScreen.mainScreen().bounds.height-64, UIScreen.mainScreen().bounds.width, barHeight));
composeBarView.addSubview(textField);
self.view.addSubView(composeBarView);
Then you should register for the UIKeyboardWillShowNotification and UIKeyboardWillHideNotification notifications:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillToggle:", name: UIKeyboardWillShowNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillToggle:", name: UIKeyboardWillHideNotification, object: nil);
Implement the keyboardWillToggle method:
func keyboardWillToggle(notfication: NSNotification){
if let userInfo = notfication.userInfo {
let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as NSValue).CGRectValue()
let startFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as NSValue).CGRectValue();
let duration:NSTimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.unsignedLongValue ?? UIViewAnimationOptions.CurveEaseInOut.rawValue
let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)
var signCorrection:CGFloat = 1;
if (startFrame.origin.y < 0 || startFrame.origin.x < 0 || endFrame.origin.y < 0 || endFrame.origin.x < 0){
signCorrection = -1;
}
let widthChange = (endFrame.origin.x - startFrame.origin.x) * signCorrection;
let heightChange = (endFrame.origin.y - startFrame.origin.y) * signCorrection;
let sizeChange = UIInterfaceOrientationIsLandscape(self.interfaceOrientation) ? widthChange : heightChange;
var frame = composeBarView.frame
frame.origin.y += (sizeChange - barHeight ?? 0.0 )
composeBarView.frame = frame;
UIView.animateWithDuration(duration,
delay: NSTimeInterval(0),
options: animationCurve,
animations: { self.view.layoutIfNeeded() },
completion: nil)
}
}
Note that we must account for the bar height, when you show the keyboard. You will need to adjust the view back to its original position.
Then when the didSelectRowAtIndexPath is called you call:
textFiled.becomeFirstResponder()
blureView.hidden = false;
Not tested yet but i think that you can do it with a modal segue?
For an exemple, when your textfield become editing you can segue to a new CellViewcontroller which can appear above your actual Tableview and insert this parameters :
func prensentationController(controller: UIPresentationController, viewControllerdaptivePresentationStyle style: UIModalPresentationtyle) -> UIViewController
let navcon = UINavigationController(UIPresentationViewController: controller.presentedViewController)
let visualEffectView = UIVisualEffectView(effect:UIBlurEffect(style: .ExtraLight))
visualEffectView.frame = navcon.view.bounds
navcon.view.insertSubview(visualEffectView, atIndex: 0)
return navcon
}

Resources