How to hide keyboard with programmatically created uitextfield - swift

I've programmatically created a uitextfield called "myTextField" in "viewDidLoad".
When I create a function to hide the keyboard when the user taps anywhere on the screen, "myTextField" isn't recognized by xcode. Is it because the textfield is created inside "viewDidLoad"?
Is there any way to access and use "myTextField" outside "viewDidLoad"?
Update: I finally had a chance to go home and copy my code to show what I mean. Here is my code:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Prepare keyboard notifications
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardDidHideNotification, object: nil);
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width;
let screenHeight = screenSize.height;
let myTextView : UITextField = UITextField(
frame : CGRect(x:10, y:(screenHeight/2), width:(screenWidth-20), height: (screenHeight/3) ) )
myTextView.backgroundColor = UIColor( red: 0.5, green: 0.5, blue:0, alpha: 1.0 )
self.scrollView.addSubview( myTextView )
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Call this method somewhere in your view controller setup code.
func keyboardWillShow(sender: NSNotification) {
let dict:NSDictionary = sender.userInfo as NSDictionary
let s:NSValue = dict.valueForKey(UIKeyboardFrameEndUserInfoKey) as NSValue;
let rect :CGRect = s.CGRectValue();
self.scrollView.contentOffset = CGPoint(x: 0, y: rect.height)
}
func keyboardWillHide(sender: NSNotification) {
let dict:NSDictionary = sender.userInfo as NSDictionary
let s:NSValue = dict.valueForKey(UIKeyboardFrameBeginUserInfoKey) as NSValue;
let rect :CGRect = s.CGRectValue();
self.scrollView.contentOffset = CGPoint(x: 0, y: 0)
}
I've created a UITextView programmatically because I'm struggling with auto layout in Xcode 6. In the meantime I've updated to Xcode beta 5 (from 4) and now even my scrollview is acting weird. So maybe I have to create it with code as well.
How can I access my textview outside of function viewDidLoad?

Declare it as a property of that class, then you can access it from anywhere. Otherwise its scope is limited to the viewDidLoad function and you can't access it from outside.
class YourClass {
var myTextField:UITextField
override func viewDidLoad() {
//init myTextField
}
func test() {
//do something with myTextField
}
}

Use this one to dismiss keyboard :-
UIApplication.sharedApplication().sendAction("resignFirstResponder", to:nil, from:nil, forEvent:nil)

Related

How to Programmatically Scroll iOS WKWebView, swift 4

So my question is: After a website(any websites on the www) has been loaded up in my iOS webview app how to make the app Programmatically Scroll vertically to any of the contents thats out of view?
// ViewController.swift
// myWebView
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
#IBOutlet weak var myWebView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear( animated )
let urlString:String = "https://www.apple.com"
let url:URL = URL(string: urlString)!
let urlRequest:URLRequest = URLRequest(url: url)
myWebView.load(urlRequest)
}
func webViewDidFinishLoad(_ webView: WKWebView) {
let scrollPoint = CGPoint(x: 0, y: webView.scrollView.contentSize.height - webView.frame.size.height)
webView.scrollView.setContentOffset(scrollPoint, animated: true )
}
}
This will also account for the possible horizontal offset of the origin of the scrollView:
var scrollPoint = self.view.convert(CGPoint(x: 0, y: 0), to: webView.scrollView)
scrollPoint = CGPoint(x: scrollPoint.x, y: webView.scrollView.contentSize.height - webView.frame.size.height)
webView.scrollView.setContentOffset(scrollPoint, animated: true)
You can manipulate the Scroll View of the webview. Below there's an example to scroll to the bottom of the view:
let scrollPoint = CGPoint(x: 0, y: yourWebView.scrollView.contentSize.height - webView.frame.size.height)
webView.scrollView.setContentOffset(scrollPoint, animated: true)
If you want to get notify your wbeview reach to top or bottom use this extension, I made it long time ago for wkwebview. webview reach top or bottom

NSButton action not working from custom NSView

I have my Push button in subview called AddContactViewController
And I'm showing it in ScrollView in another ViewController called AddContactScrollViewController.
I'm setting action for my button in AddContactViewController
But, when I click my button nothing happens.
Here are the screenshots my IB. And below is the code.
Main view controller
SubView
import Cocoa
class AddContactScrollViewController: NSViewController {
#IBOutlet weak var scrollView: NSScrollView!
var contentView: NSView?
override func viewDidLoad() {
super.viewDidLoad()
contentView = NSView(frame: NSRect(x: 0, y: 0, width: self.view.frame.width, height: 1123))
contentView!.wantsLayer = true
contentView!.layer?.backgroundColor = NSColor.clear.cgColor
let tempVC = self.storyboard?.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "addAddress")) as! AddAddressViewController
vc.view.setFrameOrigin(NSPoint(x: 0, y: 0))
vc.view.setFrameSize(NSSize(width: 1200, height: 1123))
vc.view.wantsLayer = true
contentView!.addSubview(vc.view)
scrollView.documentView = contentView
// scroll to the top
if let documentView = scrollView.documentView {
documentView.scroll(NSPoint(x: 0, y: documentView.bounds.size.height))
}
}
override func viewDidAppear() {
}
}
import Cocoa
class AddContactVeiwController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func addPhoneButtonClicked(_ sender: Any) {
print("phone button clicked")
}

UIViewController not adjusting correctly in UIScrollView for all iPhones

I am trying to replicate a Tinder like menu, with the 3 UIViewControllers in a UIScrollView and a custom menu tab on the top, with a button for each UIViewController. I am facing an interesting problem where the UIViewControllers views fit perfectly in the scrollView.frame, but only for iPhone 8. In contrast, for iPhone SE, it leaves a white margin and for iPhone 8+, it seems to overlap the views within the scrollView.view. Could someone explain why this is happening and how I can fix it?
Here's my code where I'm adjusting setting up my UIViewControllers in my UIScrollView:
import UIKit
class MainViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var navigationView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
setUpHorizontalScrollViews()
}
func setUpHorizontalScrollViews(){
let view = (
x: self.view.bounds.origin.x,
y: self.view.bounds.origin.y,
width: self.view.bounds.width,
height: self.view.bounds.height
)
let scrollWidth = 3 * view.width
let scrollHeight = view.height
scrollView.contentSize = CGSize(width: scrollWidth, height: scrollHeight)
scrollView.contentOffset.x = view.x
if let messagesView = self.storyboard?.instantiateViewController(withIdentifier: "MessagesVC") as UIViewController! {
self.addChildViewController(messagesView)
self.scrollView.addSubview(messagesView.view)
messagesView.didMove(toParentViewController: self)
messagesView.view.frame = CGRect(x: 0,
y: 0,
width: view.width,
height: view.height
)
}
if let friendsView = self.storyboard?.instantiateViewController(withIdentifier: "FriendsVC") as UIViewController! {
self.addChildViewController(friendsView)
self.scrollView.addSubview(friendsView.view)
friendsView.didMove(toParentViewController: self)
friendsView.view.frame = CGRect(x: view.width,
y: 0,
width: view.width,
height: view.height
)
}
if let settingsView = self.storyboard?.instantiateViewController(withIdentifier: "SettingsVC") as UIViewController! {
self.addChildViewController(settingsView)
self.scrollView.addSubview(settingsView.view)
settingsView.didMove(toParentViewController: self)
settingsView.view.frame = CGRect(x: 2 * view.width,
y: 0,
width: view.width,
height: view.height
)
}
// offset to the second view
self.scrollView.contentOffset.x = view.width
}
override var shouldAutorotate: Bool {
return false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is what my Setup looks like. the top is the MainViewController, containing the UIScrollView and on bottom are the 3 viewcontrollers that are supposed to go into the scrollView.
This is what I want it to look like, and the way it sets up in iPhone 8:
This is what it looks like on iPhone SE and where my problem is:
The problem is that since you are calling the setUpHorizontalScrollViews method in the viewDidLoad(), the UIViewController has yet to layout the subview, and also calculate their final size.
It is working in an iPhone 8 because most provably it has the same screen size you used in the interface builder.
Solution 1
In order to solve the problem, you can move your code to the viewDidAppear() method. However, this will cause an ugly effect once you open the UIViewController (unless you add a full screen loading).
Solution 2
Add view.layourIfNeeded() like this:
override func viewDidLoad() {
super.viewDidLoad()
view.layourIfNeeded()
setUpHorizontalScrollViews()
}

View does not animate

I have a view, which shall move up like a drawer from the bottom of the screen. But it does not do anything. It just sits there =)
Can anyone please tell me, why it is doing that?
This is my code:
import UIKit
class InfoPopUpVC: UIViewController {
var superView: UIView!
var labelText: String!
let textLabel = UILabel()
let height = CGFloat(80)
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
UIView.animateWithDuration(0.4, animations: { () -> Void in
self.view.center.y = 50
})
}
override func viewDidLoad() {
super.viewDidLoad()
setupTextLabel()
view.frame = CGRectMake(0, superView.frame.maxY-height, superView.frame.width, height)
AnimationHelper.blurBackgroundForView(view)
view.backgroundColor = .greenColor()
}
func setupTextLabel(){
textLabel.text = labelText
textLabel.frame = CGRectMake(0, 0, view.frame.width, view.frame.height)
textLabel.numberOfLines = 3
textLabel.textAlignment = .Center
textLabel.frame.inset(dx: 10, dy: 8)
textLabel.sizeToFit()
textLabel.font = UIFont(name: "HelveticaNeue-Light", size: 17)
textLabel.textColor = .whiteColor()
view.addSubview(textLabel)
}
}
Try to put your code as follow inside viewDidAppear or viewWillAppear and with dispatch async. Otherwise your animation might not work.
override func viewDidAppear(animated: Bool) {
dispatch_async(dispatch_get_main_queue(), {
UIView.animateWithDuration(0.4, animations: { () -> Void in
self.view.center.y = 50
})
})
}
You cannot animate a frame or similar property, if the UIViewis constrained using autolayout.
You have two options:
Get rid of autolayout and animate the frames Directory
Use autolayout and animate the constraints (e.g. via outlets)
See the following links for examples:
How do I animate constraint-changes
IOS: ANIMATING AUTOLAYOUT CONSTRAINTS

swift UIview removeFormSuperview

this is a test code,I want to add uiview to storyBoard ,and wait 1 second, and remove it .but the uiview doesn't appear , the code is down
var uiview1 = UIView()
uiview1.frame = CGRectMake(0, 0, 50, 50)
uiview1.backgroundColor = UIColor.blackColor()
self.view.addSubview(uiview1)
sleep(1)
uiview1.removeFromSuperview()
sleep() is not a good idea in this way. It will become totally unresponsive and block. Use NSTimer.scheduledTimerWithTimeInterval instead.
class ViewController: UIViewController {
var uiview1 = UIView()
override func viewDidLoad() {
super.viewDidLoad()
uiview1.frame = CGRectMake(0, 0, 50, 50)
uiview1.backgroundColor = UIColor.blackColor()
self.view.addSubview(uiview1)
var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("dismissView"), userInfo: nil, repeats: false)
}
func dismissView() {
uiview1.removeFromSuperview()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}