how to use protocol in uiviewcontroller ,swift - ios

How to use protocol? I can't use it. I just wanna print out "abc" when I click the start button. It didn't work. plz help me
import UIKit
import SpriteKit
protocol GameDelegate {
func gameOver()
}
class MainMenuScene: SKScene
{
var Gdelegate: GameDelegate?
override func didMoveToView(view: SKView)
{
let background = SKSpriteNode(imageNamed: "DiscsBackground")
background.size = self.size
background.zPosition = 0
background.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
self.addChild(background)
let gameTitleLabel1 = SKLabelNode(fontNamed: "Pusab")
gameTitleLabel1.text = "Disappearing"
gameTitleLabel1.fontSize = 90
gameTitleLabel1.fontColor = SKColor.whiteColor()
gameTitleLabel1.position = CGPoint(x: self.size.width/2, y: self.size.height*0.75)
gameTitleLabel1.zPosition = 1
self.addChild(gameTitleLabel1)
let gameTitleLabel2 = SKLabelNode(fontNamed: "Pusab")
gameTitleLabel2.text = "Discs"
gameTitleLabel2.fontSize = 250
gameTitleLabel2.fontColor = SKColor.whiteColor()
gameTitleLabel2.position = CGPoint(x: self.size.width/2, y: self.size.height*0.6)
gameTitleLabel2.zPosition = 1
self.addChild(gameTitleLabel2)
let gameByLabel = SKLabelNode(fontNamed: "Pusab")
gameByLabel.text = "Disappearing"
gameByLabel.fontSize = 90
gameByLabel.fontColor = SKColor.whiteColor()
gameTitleLabel2.position = CGPoint(x: self.size.width/2, y: self.size.height*0.95)
gameByLabel.zPosition = 1
self.addChild(gameByLabel)
let startLabel = SKLabelNode(fontNamed: "Pusab")
startLabel.text = "start"
startLabel.fontSize = 150
startLabel.fontColor = SKColor.whiteColor()
startLabel.position = CGPoint(x: self.size.width/2, y: self.size.height*0.35)
startLabel.zPosition = 1
startLabel.name = "startButton"
self.addChild(startLabel)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
for touch: AnyObject in touches
{
let pointOfTouch = touch.locationInNode(self)
let tappedNode = nodeAtPoint(pointOfTouch)
let tappedNodeName = tappedNode.name
if tappedNodeName == "startButton"
{
//self.scene?.view?.presentScene(nil)
Gdelegate?.gameOver()
}
}
}
}
class MHAGameViewController: UIViewController,GameDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let scene = MainMenuScene(size: CGSize(width: 1536, height: 2048))
// Configure the view.
let skView = self.view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
skView.presentScene(scene)
}
func gameOver() {/*
self.performSegueWithIdentifier("segue1", sender: self)
let alertController = UIAlertController(title: "HELP", message:
"Please wait....", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "close", style: UIAlertActionStyle.Default,handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)*/
print("abc")
}
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return .AllButUpsideDown
} else {
return .All
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}

You should set the delegate as follow :
let scene = MainMenuScene(size: CGSize(width: 1536, height: 2048))
scene.Gdelegate = self

Step: 1 - Declare protocol Just before class Declaration and Below Import stmt. (Inside Cell Class)
protocol BtnsAction: NSObjectProtocol
{
func btnLearnAction(_ sender: Any?)
}
weak var delegate: BtnsAction?
Step: 2 - Declare Button Action Method inside Cell Class.
#IBAction func btnLearnMoreAction(_ sender: UIButton) {
self.delegate?.btnLearnAction(self)
}
Step: 3 - Now, Inside ViewController.
class MyViewController_VC:ViewController, BtnsAction
//MARK: - Protocol Method -
func btnLearnAction(_ sender: Any?) {
let cell = sender as! SubCategoryCell
let indexpath = self.TableView1.indexPath(for: cell)
let dictData = self.arrFree_Listing[(indexpath?.row)!] as! NSMutableDictionary
let strId = String(dictData.value(forKey: "id") as! Int)
let detailVC = self.storyboard?.instantiateViewController(withIdentifier: "ListingDetails_InnerVC") as! ListingDetails_InnerVC
detailVC.strID = strId
self.navigationController?.pushViewController(detailVC, animated: true)
}
**Don't Forget to add **
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "_Cell") as! _Cell
cell.delegate = self
return cell
}

Related

swift 3 content mode

I have a problem with xcode: I created a draw app where you can draw on the pictures, when I open a picture and I click to draw, the image stretches,
the same thing if I change content mode (aspectFit, aspectFill)
I forget something?
how to set up the content mode correctly?
This is my code:
import UIKit
import Photos
class ViewController: UIViewController {
#IBOutlet var imageView: UIImageView!
#IBOutlet var toolIcon: UIButton!
#IBOutlet var tempImage: UIImageView!
var lastPoint = CGPoint.zero
var swiped = false
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var brushWidth:CGFloat = 10.0
var opacity:CGFloat = 1.0
var tool: UIImageView!
var isDrawing = true
var selectedImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
imageView.contentMode = UIViewContentMode.scaleAspectFill
tempImage.contentMode = UIViewContentMode.scaleAspectFill
tool = UIImageView()
tool.frame = CGRect(x:self.view.bounds.size.width, y: self.view.bounds.size.height, width: 38, height: 38)
//tool.image = #imageLiteral(resourceName: "Pen")
self.view.addSubview(tool)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){
swiped = false
if let touch = touches.first {
lastPoint = touch.location(in: self.view)
}
}
func drawLines(fromPoint:CGPoint, toPoint:CGPoint){
UIGraphicsBeginImageContext(self.view.frame.size)
tempImage.image?.draw(in: CGRect(x:0, y:0, width: self.view.frame.width,height: self.view.frame.height))
let context = UIGraphicsGetCurrentContext()
context?.move(to:CGPoint(x:fromPoint.x,y:fromPoint.y))
context?.addLine(to: CGPoint(x:toPoint.x, y: toPoint.y))
tool.center = toPoint
context?.setBlendMode(CGBlendMode.normal)
context?.setLineCap(CGLineCap.round)
context?.setLineWidth(brushWidth)
context?.setStrokeColor(UIColor(red: red, green: green, blue: blue, alpha: 1.0).cgColor)
context?.strokePath()
tempImage.image = UIGraphicsGetImageFromCurrentImageContext()
tempImage.alpha = opacity
UIGraphicsEndImageContext()
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?){
swiped = true
if let touch = touches.first {
let currentPoint = touch.location(in: self.view)
drawLines(fromPoint: lastPoint, toPoint: currentPoint)
lastPoint = currentPoint
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if !swiped {
drawLines(fromPoint: lastPoint, toPoint: lastPoint)
}
// Merge tempImageView into mainImageView
UIGraphicsBeginImageContext(imageView.frame.size)
imageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: CGBlendMode.normal, alpha: 1.0)
tempImage.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: CGBlendMode.normal, alpha: opacity)
imageView.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
tempImage.image = nil
}
#IBAction func reset(_ sender: Any) {
self.imageView.image = nil
}
#IBAction func colorPicked(_ sender: UIButton) {
if sender.tag == 0 {
(red,green,blue) = (1,0,0)
}else if sender.tag == 1 {
(red,green,blue) = (0,1,0)
}else if sender.tag == 2{
(red,green,blue) = (0,0,1)
}else if sender.tag == 3 {
(red,green,blue) = (1,0,1)
}else if sender.tag == 4{
(red,green,blue) = (1,1,0)
}else if sender.tag == 5 {
(red,green,blue) = (0,1,1)
}else if sender.tag == 6{
(red,green,blue) = (1,1,1)
}else if sender.tag == 7 {
(red,green,blue) = (0,0,0)
}
}
#IBAction func save(_ sender: Any) {
let actionSheet = UIAlertController(title: "Pick your options", message: "", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Pick an image", style: .default, handler: { (_) in
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = false
imagePicker.delegate = self
self.present(imagePicker, animated: true, completion: nil)
}))
actionSheet.addAction(UIAlertAction(title: "Save your drawing", style: .default, handler: {(_) in
if let image = self.imageView.image {
UIImageWriteToSavedPhotosAlbum(image, nil,nil,nil)
}
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
present(actionSheet, animated: true, completion: nil)
}
#IBAction func erase(_ sender: Any) {
if (isDrawing) {
(red,green,blue) = (1,1,1)
tool.image = #imageLiteral(resourceName: "Gomma")
toolIcon.setImage(#imageLiteral(resourceName: "Pen"), for: .normal)
}else {
(red,green,blue) = (0,0,0)
tool.image = nil
toolIcon.setImage(#imageLiteral(resourceName: "Gomma"), for: .normal)
}
isDrawing = !isDrawing
}
#IBAction func setting(_ sender: Any) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
let settingsVc = segue.destination as! SettingViewController
settingsVc.delegate = self
settingsVc.red = red
settingsVc.green = green
settingsVc.blue = blue
settingsVc.brush = brushWidth
settingsVc.opacity = opacity
}
}
extension ViewController:UINavigationControllerDelegate,UIImagePickerControllerDelegate,SettingsVCDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let imagePicked = info[UIImagePickerControllerOriginalImage] as? UIImage {
self.selectedImage = imagePicked
self.imageView.image = selectedImage
self.tempImage.image = selectedImage
dismiss(animated: true, completion: nil)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func settingsViewControllerDidFinish(_settingsVc: SettingViewController) {
self.red = _settingsVc.red
self.green = _settingsVc.green
self.blue = _settingsVc.blue
self.brushWidth = _settingsVc.brush
self.opacity = _settingsVc.opacity
}
}

UITableView's contentInset.top is 20 points larger than it should be in iOS10

I have a SearchViewController, and as part of this ViewController I have a UISearchController (with a SearchResultsController called SearchResultsTableViewController). I notice that my SearchResultsTableViewController's UITableView contentInset.top is 20 points more than it should be, despite it being fine on iOS8/9 and having automaticallyAdjustScrollViewInsets = true. If I perform a segue from this ViewController to another, then go back, I see that the contentInset.top increases another 20 points. Again, this does not occur on iOS8/9. Here are a couple of images showing this behavior.
Here is the code for the two relevant ViewControllers.
class SearchViewController: UIViewController, UISearchBarDelegate, UISearchControllerDelegate {
#IBOutlet var tableView: UITableView!
#IBOutlet var backgroundImageView: UIImageView!
var searchController: UISearchController!
var backBarButtonItem: UIBarButtonItem!
var searchButtonTapped = false
#IBOutlet var titleLabel: SpringLabel!
#IBOutlet var loadingIndicatorView: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
let searchResultsVC = self.storyboard!.instantiateViewController(withIdentifier: "SearchResultsTableViewController") as! SearchResultsTableViewController
searchResultsVC.searchController = self
searchController = UISearchController(searchResultsController: searchResultsVC)
searchController.searchResultsUpdater = searchResultsVC
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = true
searchController.delegate = self
searchController.searchBar.delegate = self
searchController.searchBar.placeholder = "Search Courses"
searchController.view.backgroundColor = UIColor.clear
searchController.searchBar.keyboardAppearance = .dark
self.setSearchBarCaretColor(UIColor(red: 0.24, green: 0.34, blue: 0.19, alpha: 1.0))
self.setSearchBarFontSize(17.0)
self.navigationItem.titleView = searchController.searchBar
self.definesPresentationContext = true
self.backBarButtonItem = self.navigationItem.leftBarButtonItem
self.backgroundImageView.clipsToBounds = true
self.titleLabel.alpha = 0
self.titleLabel.layer.shadowColor = UIColor.black.cgColor
self.titleLabel.layer.shadowOpacity = 0.8
self.titleLabel.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)
self.titleLabel.layer.shouldRasterize = true
self.titleLabel.layer.rasterizationScale = UIScreen.main.scale
self.loadingIndicatorView.layer.zPosition = CGFloat.greatestFiniteMagnitude
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.perform(#selector(SearchViewController.showKeyboard), with: nil, afterDelay: 0.01)
searchBarTextDidBeginEditing(searchController.searchBar)
}
func showKeyboard() {
self.searchController.searchBar.becomeFirstResponder()
}
func hideKeyboard() {
self.searchController.searchBar.resignFirstResponder()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.titleLabel.delay = 0.1
self.titleLabel.animation = "zoomIn"
self.titleLabel.duration = 0.6
self.titleLabel.animate()
let selectedRowIndexPath = self.tableView.indexPathForSelectedRow
if ((selectedRowIndexPath) != nil) {
self.tableView.deselectRow(at: selectedRowIndexPath!, animated: true)
self.transitionCoordinator?.notifyWhenInteractionEnds({ context in
if (context.isCancelled) {
self.tableView.selectRow(at: selectedRowIndexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)
}
})
}
}
func setSearchBarCaretColor(_ color : UIColor) {
let view = searchController.searchBar.subviews[0]
let subViewsArray = view.subviews
for subView in subViewsArray {
if subView.isKind(of: UITextField.self) {
subView.tintColor = color
}
}
}
func setSearchBarFontSize(_ pointSize : CGFloat) {
let view = searchController.searchBar.subviews[0]
let subViewsArray = view.subviews
for subView in subViewsArray {
if subView.isKind(of: UITextField.self) {
let textField = subView as! UITextField
textField.font = UIFont.systemFont(ofSize: pointSize)
}
}
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
//This doesn't animate for some reason, so don't use it.
if (UI_USER_INTERFACE_IDIOM() != .pad) { //Because the iPad (for some reason) doesn't ever show the Cancel button, so keep the back button.
UIView.animate(withDuration: 0.3, animations: { self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: UIView()) }, completion: { Void in
self.navigationItem.setHidesBackButton(true, animated: false)
})
}
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
if (self.searchButtonTapped == false) {
self.navigationItem.leftBarButtonItem = self.backBarButtonItem
self.navigationItem.setHidesBackButton(false, animated: true)
} else {
self.searchButtonTapped = false
}
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
self.navigationItem.leftBarButtonItem = self.backBarButtonItem
self.navigationItem.setHidesBackButton(false, animated: true)
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
self.searchButtonTapped = true
searchBar.resignFirstResponder()
}
}
Now here is SearchResultsTableViewController:
class SearchResultsTableViewController: UITableViewController, UISearchResultsUpdating {
var resultsArray = [CourseResult]()
var emptySearchResultsView : EmptySearchResultsView!
var keyboardActive = false
var keyboardHeight : CGFloat = 0.0
var searchController : SearchViewController!
var query = PFQuery(className: "Course")
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.backgroundColor = UIColor.clear
self.tableView.estimatedRowHeight = 140
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.keyboardDismissMode = .onDrag
self.emptySearchResultsView = EmptySearchResultsView.construct(self) as EmptySearchResultsView
emptySearchResultsView.translatesAutoresizingMaskIntoConstraints = true
self.emptySearchResultsView.isHidden = true
self.tableView.addSubview(emptySearchResultsView)
query.whereKey("institution", equalTo: "College")
query.limit = 20
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
self.registerKeyboardNotifications()
let selectedRowIndexPath = self.tableView.indexPathForSelectedRow
if ((selectedRowIndexPath) != nil) {
self.tableView.deselectRow(at: selectedRowIndexPath!, animated: true)
self.transitionCoordinator?.notifyWhenInteractionEnds({ context in
if (context.isCancelled) {
self.tableView.selectRow(at: selectedRowIndexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)
}
})
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.unregisterKeyboardNotifications()
}
var lastSearch = ""
func updateSearchResults(for searchController: UISearchController) {
guard searchController.isActive else { return }
if (lastSearch == searchController.searchBar.text!) {
return
}
self.lastSearch = searchController.searchBar.text!
query.cancel()
self.emptySearchResultsView.isHidden = true
if (searchController.searchBar.text?.characters.count == 0) {
resultsArray.removeAll()
self.tableView.reloadData()
}
if ((searchController.searchBar.text?.characters.count)! > 0) {
self.searchController.loadingIndicatorView.startAnimating()
var searchString = searchController.searchBar.text!
searchString = searchString.lowercased()
var searchStringArray = searchString.components(separatedBy: " ")
searchStringArray = searchStringArray.filter { $0 != "" }
//print(searchStringArray.description)
query.whereKey("searchTerms", containsAllObjectsIn: searchStringArray)
query.findObjectsInBackground(block: { (results, error) -> Void in
if (error == nil) {
self.resultsArray = []
let courseResultsArray = results! as [PFObject]
for result in courseResultsArray {
//removed all of this jargon.
}
self.searchController.loadingIndicatorView.stopAnimating()
self.tableView.reloadData()
if (self.resultsArray.count == 0) {
self.emptySearchResultsView.isHidden = false
} else {
self.emptySearchResultsView.isHidden = true
}
} else {
print(error?.localizedDescription)
self.searchController.loadingIndicatorView.stopAnimating()
}
})
}
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if (self.keyboardActive == true) {
self.emptySearchResultsView.frame = CGRect(x: 0, y: 0, width: self.tableView.bounds.width, height: self.tableView.bounds.height - self.keyboardHeight - self.tableView.contentInset.top)
self.emptySearchResultsView.setNeedsLayout()
} else {
self.emptySearchResultsView.frame = CGRect(x: 0, y: 0, width: self.tableView.bounds.width, height: self.tableView.bounds.height - self.tableView.contentInset.top)
self.emptySearchResultsView.setNeedsLayout()
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return resultsArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellContent: CourseResult = self.resultsArray[(indexPath as NSIndexPath).row]
let cell = tableView.dequeueReusableCell(withIdentifier: "CourseResultTableViewCell", for: indexPath) as! CourseResultTableViewCell
cell.backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
cell.backgroundColor = UIColor.clear
cell.courseLabel.text = cellContent.courseCode + " - " + cellContent.courseName
cell.universityLabel.text = cellContent.university
cell.facultyLabel.text = cellContent.faculty
cell.leftHandSideImageView.image = UIImage(named: cellContent.faculty)
cell.leftHandSideImageView.layer.shadowColor = UIColor.black.cgColor
cell.leftHandSideImageView.layer.shadowOpacity = 0.6
cell.leftHandSideImageView.layer.shouldRasterize = true
cell.leftHandSideImageView.layer.rasterizationScale = UIScreen.main.scale
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let schedulesVC = self.storyboard!.instantiateViewController(withIdentifier: "SchedulesViewController") as! SchedulesViewController
schedulesVC.selectedCourse = self.resultsArray[(indexPath as NSIndexPath).row]
self.searchController.show(schedulesVC, sender: tableView)
}
func registerKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(SearchResultsTableViewController.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(SearchResultsTableViewController.keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func unregisterKeyboardNotifications() {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func keyboardWillShow(_ notification: Notification) {
if (UI_USER_INTERFACE_IDIOM() != .phone) { //Because devices like iPads don't have they keyboards affect the error screen visibility much.
return
}
if let keyboardFrame = ((notification as NSNotification).userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue {
UIView.animate(withDuration: 0.6, animations: { self.emptySearchResultsView.frame = CGRect(x: 0, y: 0, width: self.tableView.bounds.width, height: self.tableView.bounds.height - keyboardFrame.height - self.tableView.contentInset.top)
self.emptySearchResultsView.layoutIfNeeded()
})
self.keyboardActive = true
self.keyboardHeight = keyboardFrame.height
}
}
func keyboardWillHide(_ notification: Notification) {
if (UI_USER_INTERFACE_IDIOM() != .phone) {
return
}
UIView.animate(withDuration: 0.6, animations: { self.emptySearchResultsView.frame = CGRect(x: 0, y: 0, width: self.tableView.bounds.width, height: self.tableView.bounds.height - self.tableView.contentInset.top)
self.emptySearchResultsView.layoutIfNeeded()
})
self.keyboardActive = false
}
}
Each of these ViewControllers have their own representation in the storyboard.
Does anyone have an idea why I see this behavior, which is only seen in iOS10? The issue occurs on a wide range of devices from what I have tested.
Note: Just ignore any string parsing code related to the results or any other related code. I removed some of this stuff to try to make the code a little more coherent, along with json parsing code, etc
The only solution that has worked for me (which is not ideal) is to check if the device is running iOS10 and to dynamically adjust the contentInset.top based on the height of the status bar and navigationBar. Obviously I had to turn off automaticallyAdjustScrollViewInsets to do this.

How to call a function that is defined in a different view controller?

I'm trying to call the function called "kick". Inside it is a CAAnimation that I am playing on this man I made. So usually I would just call the function in the same view controller as it was made in. But because I have a HUD/overlay scene the displays over my 3D game. And the HUD/overlayscene is made in a different view controller specifically just to set up the HUD I can't get the HUD view controller to Recognize any functions from the Main View Controller.
MainViewController:
Code:
class GameViewController: UIViewController, ADBannerViewDelegate, SKPhysicsContactDelegate, SKSceneDelegate, SCNSceneRendererDelegate, SCNPhysicsContactDelegate{
var HUDView: HUD!
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func viewDidLoad() {
super.viewDidLoad()
//-----Scene-Setup----------
let scnView = self.view as! SCNView
scnView.scene = FieldScene
scnView.playing = true
scnView.loops = true
self.HUDView = HUD(size: CGSizeMake(100, 100))
scnView.overlaySKScene = self.HUDView
scnView.delegate = self
scnView.overlaySKScene!.delegate = self
scnView.overlaySKScene!.userInteractionEnabled = true
scnView.backgroundColor = UIColor.whiteColor()
scnView.allowsCameraControl = true
scnView.showsStatistics = false
let GuyScene = SCNScene(named: "art.scnassets/The1.dae")
let Guy: SCNNode = GuyScene!.rootNode.childNodeWithName("Armature", recursively: true)!
let GuyBody: SCNNode = GuyScene!.rootNode.childNodeWithName("Cube", recursively: true)!
//----Giveing it a physics---------
let collisionCapsuleRadius2 = CGFloat(0.1)
let collisionCapsuleHeight2 = CGFloat(0.1)
Guy.position = SCNVector3(x: -30.0, y: 30.0, z: 0.0)
Guy.scale = SCNVector3Make(50, 50, 50)
Guy.rotation = SCNVector4Make(0, 1, 0, 1 )
Guy.physicsBody = SCNPhysicsBody(type: .Dynamic, shape:SCNPhysicsShape(geometry: SCNCapsule(capRadius: collisionCapsuleRadius2, height: collisionCapsuleHeight2), options:nil))
Guy.physicsBody?.affectedByGravity = true
Guy.physicsBody?.friction = 0 //
Guy.physicsBody?.restitution = 1 //bounceness of the object
Guy.physicsBody?.angularDamping = 1 // rotationess
Guy.physicsBody?.mass = 1
Guy.physicsBody?.rollingFriction = 0
scnView.scene!.rootNode.addChildNode(Guy)
scnView.scene!.rootNode.addChildNode(GuyBody)
}
//Ok Kick function gets declared right here
func Kick() {
//-----Animate-Guy-----Working-Perfectly-----------
let KickAnimation = CAAnimation.animationWithSceneNamed("art.scnassets/The1Anima.dae")!
Guy.addAnimation(KickAnimation, forKey: "Go")
Guy.removeAnimationForKey("Go", fadeOutDuration: 3.0)
}
}
extension CAAnimation {
class func animationWithSceneNamed(name: String) -> CAAnimation? {
var animation: CAAnimation?
if let scene = SCNScene(named: name) {
scene.rootNode.enumerateChildNodesUsingBlock({ (child, stop) in
if child.animationKeys.count > 0 {
animation = child.animationForKey(child.animationKeys.first!)
stop.initialize(true)
}
})
}
return animation
}
}
//Ok Below is my HUD/Overlayscene which holds the button that i would like call the function in.
extension GameViewController {
// was never used
}
class HUD: SKScene {
//-----------------Controller-Buttons----------------------
var ButtonA = SKSpriteNode(imageNamed:"EnhancedAButton")
override init(size: CGSize) {
super.init(size: size)
//----A-Button--Creation -------------------
ButtonA.size = CGSize(width: 7, height: 11)
ButtonA.anchorPoint = CGPointMake(-11.35, -0.6)
ButtonA.zPosition = 0
ButtonA.alpha = 0.45
self.addChild(ButtonA)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
//Ok here is the function I need to put "Kick()" inside it but when I do it doenst recognize it because the function wasnt declared in this view controller
func AButtonPressed() {
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
for touch: AnyObject in touches {
let location1 = touch.locationInNode(self)
if self.nodeAtPoint(location1) == self.ButtonA {
AButtonPressed()
print("AButtonPressed")
}
}
}
}
enter image description here
enter image description here
This is practically the best way to handle this. Other methods are messy while this is the most decoupled natural way to handle it. If you have any questions, let me know.
extension GameViewController: GameDelegate {
func Kick() {
//-----Animate-Guy-----Working-Perfectly-----------
let KickAnimation = CAAnimation.animationWithSceneNamed("art.scnassets/The1Anima.dae")!
Guy.addAnimation(KickAnimation, forKey: "Go")
Guy.removeAnimationForKey("Go", fadeOutDuration: 3.0)
}
}
protocol GameDelegate {
func Kick()
}
class HUD: SKScene {
var delegate: GameDelegate?
override init(size: CGSize) {
super.init(size: size)
//this calls Kick anywhere in the HUD class
delegate?.Kick()
//----A-Button--Creation -------------------
ButtonA.size = CGSize(width: 7, height: 11)
ButtonA.anchorPoint = CGPointMake(-11.35, -0.6)
ButtonA.zPosition = 0
ButtonA.alpha = 0.45
self.addChild(ButtonA)
}
}
after the line that is inside of GameViewController's viewDidLoad()
//below this line
self.HUDView = HUD(size: CGSizeMake(100, 100))
//add in
self.HUDView.delegate = self
After all of this, is added in, you can delete the copy of Kick that is not in the extension. Both controllers can access the function.

Game Center "Done" button issue?

The "Done" button in Game Center will not dismiss the controller. My code to dismiss the view controller is exactly the same everywhere I look. I've looked at similar questions on here but no luck. Can anyone help me?
GameScene.Swift (This serves as my start menu )
class GameScene: SKScene, GKGameCenterControllerDelegate {
var startBtn = SKSpriteNode(imageNamed: "play button")
var title = SKLabelNode(fontNamed: "AvenirNext-UltraLight")
var leaderboardButtonImage = SKSpriteNode(imageNamed: "leaderboard button")
override func didMoveToView(view: SKView) {
let bounds = UIScreen.mainScreen().bounds
self.scene?.size = CGSize(width: bounds.size.width, height: bounds.size.height)
scene?.backgroundColor = UIColor.whiteColor()
startBtn.position = CGPoint(x: self.frame.width / 2 - 100, y: self.frame.height / 2)
startBtn.size = CGSize(width: 140, height: 55)
self.addChild(startBtn)
leaderboardButtonImage.position = CGPoint(x: self.frame.width / 2 + 100, y: self.frame.height / 2)
leaderboardButtonImage.size = CGSize(width: 140, height: 55)
self.addChild(leaderboardButtonImage)
}
func showLeaderboard() {
let vc = self.view?.window?.rootViewController
let gc = GKGameCenterViewController()
gc.viewState = GKGameCenterViewControllerState.Leaderboards
gc.leaderboardIdentifier = "I removed this part"
vc!.presentViewController(gc, animated: true, completion: nil)
}
func gameCenterViewControllerDidFinish(gameCenterViewController: GKGameCenterViewController) {
gameCenterViewController.dismissViewControllerAnimated(true, completion: nil)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in (touches ) {
let location = touch.locationInNode(self)
if (startBtn.containsPoint(location)) {
self.view?.presentScene(GamePlayScene(), transition: SKTransition.crossFadeWithDuration(1.0))
GamePlayScene().scaleMode = .ResizeFill
startBtn.removeFromParent()
title.removeFromParent()
leaderboardButtonImage.removeFromParent()
}
if (leaderboardButtonImage.containsPoint(location)) {
showLeaderboard()
}
}
}
}
In my func showLeaderboard(), I had to add the line gc.gameCenterDelegate = self which made the "Done" button work.
I hope other people who have this same problem see this potential fix.
func showLeaderboard() {
let vc = self.view?.window?.rootViewController
let gc = GKGameCenterViewController()
gc.viewState = GKGameCenterViewControllerState.Leaderboards
gc.gameCenterDelegate = self
gc.leaderboardIdentifier = "I removed this part"
vc!.presentViewController(gc, animated: true, completion: nil)
}

How to implement SwipeView?

I want to swipe each image to switch to another image like gallery app. I am now using this https://github.com/nicklockwood/SwipeView, but I don't know how to implement it. Should I drag a collection view inside my PhotoDetailViewController, or I only use it in coding. May anyone help me with this.
Here is my code:
import Foundation
import UIKit
import AAShareBubbles
import SwipeView
class PhotoDetailViewController: UIViewController, AAShareBubblesDelegate, SwipeViewDataSource, SwipeViewDelegate {
#IBOutlet var topView: UIView!
#IBOutlet var bottomView: UIView!
#IBOutlet var photoImageView: UIImageView!
var photoImage = UIImage()
var checkTapGestureRecognize = true
var swipeView: SwipeView = SwipeView.init(frame: CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, height: UIScreen.mainScreen().bounds.height))
override func viewDidLoad() {
title = "Photo Detail"
super.viewDidLoad()
photoImageView.image = photoImage
swipeView.dataSource = self
swipeView.delegate = self
let swipe = UISwipeGestureRecognizer(target: self, action: "swipeMethod")
swipeView.addGestureRecognizer(swipe)
swipeView.addSubview(photoImageView)
swipeView.pagingEnabled = false
swipeView.wrapEnabled = true
}
func swipeView(swipeView: SwipeView!, viewForItemAtIndex index: Int, reusingView view: UIView!) -> UIView! {
return photoImageView
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("SwipeCell", forIndexPath: indexPath) as! SwipeViewPhotoCell
return cell
}
#IBAction func onBackClicked(sender: AnyObject) {
self.navigationController?.popViewControllerAnimated(true)
}
#IBAction func onTabGestureRecognize(sender: UITapGestureRecognizer) {
print("on tap")
if checkTapGestureRecognize == true {
bottomView.hidden = true
topView.hidden = true
self.navigationController?.navigationBarHidden = true
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width
let screenHeight = screenSize.height
photoImageView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
checkTapGestureRecognize = false
showAminationOnAdvert()
}
else if checkTapGestureRecognize == false {
bottomView.hidden = false
topView.hidden = false
self.navigationController?.navigationBarHidden = false
checkTapGestureRecognize = true
}
}
func showAminationOnAdvert() {
let transitionAnimation = CATransition();
transitionAnimation.type = kCAEmitterBehaviorValueOverLife
transitionAnimation.subtype = kCAEmitterBehaviorValueOverLife
transitionAnimation.duration = 2.5
transitionAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transitionAnimation.fillMode = kCAFillModeBoth
photoImageView.layer.addAnimation(transitionAnimation, forKey: "fadeAnimation")
}
#IBAction func onShareTouched(sender: AnyObject) {
print("share")
let myShare = "I am feeling *** today"
let shareVC: UIActivityViewController = UIActivityViewController(activityItems: [myShare], applicationActivities: nil)
self.presentViewController(shareVC, animated: true, completion: nil)
// print("share bubles")
// let shareBubles: AAShareBubbles = AAShareBubbles.init(centeredInWindowWithRadius: 100)
// shareBubles.delegate = self
// shareBubles.bubbleRadius = 40
// shareBubles.sizeToFit()
// //shareBubles.showFacebookBubble = true
// shareBubles.showTwitterBubble = true
// shareBubles.addCustomButtonWithIcon(UIImage(named: "twitter"), backgroundColor: UIColor.whiteColor(), andButtonId: 100)
// shareBubles.show()
}
#IBAction func playAutomaticPhotoImages(sender: AnyObject) {
animateImages(0)
}
func animateImages(no: Int) {
var number: Int = no
if number == images.count - 1 {
number = 0
}
let name: String = images[number]
self.photoImageView!.alpha = 0.5
self.photoImageView!.image = UIImage(named: name)
//code to animate bg with delay 2 and after completion it recursively calling animateImage method
UIView.animateWithDuration(2.0, delay: 0.8, options:UIViewAnimationOptions.CurveEaseInOut, animations: {() in
self.photoImageView!.alpha = 1.0;
},
completion: {(Bool) in
number++;
self.animateImages(number);
print(String(images[number]))
})
}
}
Just drag and drop a UIView to your storyboard/XIB, and set its customclass to SwipeView.
Also set the delegate and datasource to the view controller which includes the UIView you just dragged.
Then in the viewcontroller, implement the required delegate methods similar to how you'd implement the methods for a tableview.

Resources