Best approach: Swipe between scrollable views or view controllers - ios

I have a few screens in my app that look like this (not from my app, found it online):
One of them is an actual intro screen, like the one above and the other will display some data and an "I AGREE" button on the last view.
In all cases the user will have to swipe between the views / view controllers.
I know I can swipe between view controllers like this: Setting up UIScrollView to swipe between 3 view controllers and I can also swipe between views using this:
func respondToSwipeGesture(_ gesture: UIGestureRecognizer)
{
print("respondToSwipeGesture")
if let swipeGesture = gesture as? UISwipeGestureRecognizer
{
switch swipeGesture.direction
{
case UISwipeGestureRecognizerDirection.right:
if(isLeftToRightActive == true)
{
print("Swiped right")
moveTheMainView()
}
case UISwipeGestureRecognizerDirection.left:
if(isLeftToRightActive == false)
{
print("Swiped left")
moveTheMainView()
}
default:
break
}
}
}
func moveTheMainView()
{
print("moveTheMainView")
let mainViewContainerHeight = self.vMainViewContainer.frame.height
let mainViewContainerWidth = self.vMainViewContainer.frame.width
let mainViewContainerModifiedLeft : CGFloat = mainViewContainerWidth / 2
if(isLeftToRightActive == false)
{
print("Move the main view to the right")
let urlCRTable = Bundle.main.url(forResource: "CRCharts", withExtension: "html")
let crTableRequestObj = URLRequest(url: urlCRTable!)
self.wvCRTable.loadRequest(crTableRequestObj)
ivIndicator.image = UIImage(named: "SecondOn")
isLeftToRightActive = true
}
else
{
print("Move the main view to the left")
let urlCRTable = Bundle.main.url(forResource: "CRTable", withExtension: "html")
let crTableRequestObj = URLRequest(url: urlCRTable!)
self.wvCRTable.loadRequest(crTableRequestObj)
ivIndicator.image = UIImage(named: "FirstOn")
isLeftToRightActive = false
}
}
So I was wondering what would be the best / correct approach to do this: to use multiple view controllers or to use multiple views in the same view controller? Or is there any other way that is considered corect?

I usually do walkthroughs like this, using PageViewController. You should create scenes like this on screenshots. And classes:
class WalkthroughContentViewController: UIViewController {
#IBOutlet var headingLabel: UILabel!
#IBOutlet var contentLabel: UILabel!
#IBOutlet var contentImageView: UIImageView!
#IBOutlet var pageControl: UIPageControl!
#IBOutlet var forwardButton: UIButton!
var index = 0
var heading = ""
var imageFile = ""
var content = ""
override func viewDidLoad() {
super.viewDidLoad()
headingLabel.text = heading
contentLabel.text = content
contentImageView.image = UIImage(named: imageFile)
pageControl.currentPage = index
switch index {
case 0...1: forwardButton.setTitle("NEXT", for: .normal)
case 2: forwardButton.setTitle("DONE", for: .normal)
default: break
}
}
#IBAction func nextButtonTapped(sender: UIButton) {
switch index {
case 0...1: // Next Button
let pageViewController = parent as! WalkthroughPageViewController
pageViewController.forward(index: index)
case 2: // Done Button
UserDefaults.standard.set(true, forKey: "hasViewedWalkthrough")
// Add Quick Actions
if traitCollection.forceTouchCapability == UIForceTouchCapability.available {
let bundleIdentifier = Bundle.main.bundleIdentifier
let shortcutItem1 = UIApplicationShortcutItem(type: "\(bundleIdentifier).OpenFavorites", localizedTitle: "Show Favorites", localizedSubtitle: nil, icon: UIApplicationShortcutIcon(templateImageName: "favorite-shortcut"), userInfo: nil)
let shortcutItem2 = UIApplicationShortcutItem(type: "\(bundleIdentifier).OpenDiscover", localizedTitle: "Discover Restaurants", localizedSubtitle: nil, icon: UIApplicationShortcutIcon(templateImageName: "discover-shortcut"), userInfo: nil)
let shortcutItem3 = UIApplicationShortcutItem(type: "\(bundleIdentifier).NewRestaurant", localizedTitle: "New Restaurant", localizedSubtitle: nil, icon: UIApplicationShortcutIcon(type: .add), userInfo: nil)
UIApplication.shared.shortcutItems = [shortcutItem1, shortcutItem2, shortcutItem3]
}
dismiss(animated: true, completion: nil)
default: break
}
}
}
class WalkthroughPageViewController: UIPageViewController, UIPageViewControllerDataSource {
var pageHeadings = ["Personalize", "Locate", "Discover"]
var pageImages = ["foodpin-intro-1", "foodpin-intro-2", "foodpin-intro-3"]
var pageContent = ["Pin your favorite restaurants and create your own food guide",
"Search and locate your favourite restaurant on Maps",
"Find restaurants pinned by your friends and other foodies around the world"]
override func viewDidLoad() {
super.viewDidLoad()
// Set the data source to itself
dataSource = self
// Create the first walkthrough screen
if let startingViewController = contentViewController(at: 0) {
setViewControllers([startingViewController], direction: .forward, animated: true, completion: nil)
}
}
// MARK: - UIPageViewControllerDataSource Methods
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
var index = (viewController as! WalkthroughContentViewController).index
index -= 1
return contentViewController(at: index)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
var index = (viewController as! WalkthroughContentViewController).index
index += 1
return contentViewController(at: index)
}
// MARK: - Helper Methods
func contentViewController(at index: Int) -> WalkthroughContentViewController? {
if index < 0 || index >= pageHeadings.count {
return nil
}
// Create a new view controller and pass suitable data.
if let pageContentViewController = storyboard?.instantiateViewController(withIdentifier: "WalkthroughContentViewController") as? WalkthroughContentViewController {
pageContentViewController.imageFile = pageImages[index]
pageContentViewController.heading = pageHeadings[index]
pageContentViewController.content = pageContent[index]
pageContentViewController.index = index
return pageContentViewController
}
return nil
}
func forward(index: Int) {
if let nextViewController = contentViewController(at: index + 1) {
setViewControllers([nextViewController], direction: .forward, animated: true, completion: nil)
}
}
}

If you have more items, you should use UICollectionView, each item (with red background in your image) will be a cell.
This way the views will be reused, better performance.

You should use UIPageViewController for this approach .
How to use check : https://stackoverflow.com/a/25416608/3901620
Third Library for this

Related

How to identify i come from which button

These both button shows same ViewController.
ViewController1.swift
#objc func btnEdit()
{
print("Edit")
let editDeptt = self.storyboard?.instantiateViewController(withIdentifier: "Add Department") as! AddDepartmentVC
self.navigationController?.pushViewController(editDeptt, animated: true)
}
#IBAction func btnNewDeptt(_ sender: Any)
{
let addDepttVC = self.storyboard?.instantiateViewController(withIdentifier: "Add Department") as! AddDepartmentVC
self.navigationController?.pushViewController(addDepttVC, animated: true)
}
ViewController2.swift
override func viewDidLoad() {
super.viewDidLoad()
//How to identify i come from which button
}
Add a property to your AddApartmentVC called action and set it before you push the view controller.
First create an enum:
enum Action {
case edit, newDept, unknown
}
Then define this property in your AddApartmentVC:
var action = Action.unknown
Then in your buttons' actions, set the property to the desired value:
editDeptt.action = .edit
or
addDepttVC.action = .newDept
Finally, in viewDidLoad(), check the value:
override func viewDidLoad() {
super.viewDidLoad()
switch(action) {
case .edit:
// do something for edit
case .newDept
// create a new Dept
case .unknown
print("what am I doing here?")
}
}
Add an instance variable name identify in your AddDepartmentVC and pass set the value of the same from your current VC like this
let editDeptt = self.storyboard?.instantiateViewController(withIdentifier: "Add Department") as! AddDepartmentVC
editDeptt.identify = "button1"
Then you can push it and check the variable in AddDepartmentVC
In ViewController2.swift, declare one variable like this
class ViewController2: UIViewController{
let var originTag: Int = 0
}
override func viewDidLoad() {
super.viewDidLoad()
if originTag == 0
{
// come from button 1 - btnEdit
}
else
{
// come from button 2 - btnNewDeptt
}
}
In ViewController 1, set originTag like this.
#objc func btnEdit()
{
print("Edit")
let editDeptt = self.storyboard?.instantiateViewController(withIdentifier: "Add Department") as! AddDepartmentVC
editDeptt.originTag = 0
self.navigationController?.pushViewController(editDeptt, animated: true)
}
#IBAction func btnNewDeptt(_ sender: Any)
{
let addDepttVC = self.storyboard?.instantiateViewController(withIdentifier: "Add Department") as! AddDepartmentVC
addDepttVC.originTag = 1
self.navigationController?.pushViewController(addDepttVC, animated: true)
}
Simply assign a tag for button -
Button1.tag=1
Button2.tag=2
Then check your button -
func onClickButton(sender: UIButton){
switch(sender.tag){
case 101 :
print("I am from button 1")
default :
print("I am from button 2")
}
}
use following it's perfectly working for you.
Take one public variable above class like below in Viewcontroller1.Swift
public var btnComingFrom = "first"
#objc func btnEdit()
{
btnComingFrom = "first"
print("Edit")
let editDeptt =
self.storyboard?.instantiateViewController(withIdentifier: "Add Department")
as! AddDepartmentVC
self.navigationController?.pushViewController(editDeptt, animated: true)
}
#IBAction func btnNewDeptt(_ sender: Any)
{
btnComingFrom = "second"
let addDepttVC = self.storyboard?.instantiateViewController(withIdentifier: "Add Department") as! AddDepartmentVC
self.navigationController?.pushViewController(addDepttVC, animated: true)
}
ViewController2.swift
override func viewDidLoad()
{
super.viewDidLoad()
if btnComingFrom == "first"
{
print("you are coming from first button")
}
if btnComingFrom == "second"
{
print("you are coming from second button")
}
}

Hide a website button in my tableViewCell

This is code for my custom tableViewCell
#IBOutlet weak var webButton: UIButton!
func update(place:EClass) {
self.place = place
myLabel.text = place.name
myImage.image = nil
myLabel2.text = place.getDescription()
// IF (didClickWebsite) THE SITE DOESN'T EXIST, MAKE INVISIBLE THE BUTTON webButton
if let url = place.photos?.first?.getPhotoURL(maxWidth: maxWidht) {
myImage.af_setImage(withURL: url)
}
}
#IBAction func goToWebSite(_ sender: Any) {
if let place = place, let delegate = delegate {
delegate.didClickWebsite(place: place)
}
}
where I recently added this button #IBOutlet weak var webButton: UIButton!
and this extension is in the VC of my tableView
extension CourseClass2: PlaceCellDelegate {
func didClickWebsite(place: EClass) {
NearbyZone.getZoneDetails(place: place) { (place) in
if let website = place.details?["website"] as? String, let url = URL(string: website) {
let svc = SFSafariViewController.init(url: url)
self.navigationController?.pushViewController(svc, animated: true)
}
}
}
}
what I would like to do is to tell the func update in my custom tableViewCell that if the function didClickWebsite does not produce any results (in this case when the site does not exist) it has to hide the website button, how caI i do this?

Programmatically advance UIPageViewController - Swift

This is my first attempt at an IOS app, and I have no experience with swift, and a lot of the code is borrowed from the web and edited.
I am trying to create a set of slides. I go from the main Landing page to another View Controller, TestVC, that runs the slides. The landing page and the slides work. I can swipe back and forth. I am now trying to add a timer so that the slides auto advance every 5 or so seconds.
I believe that the code that needs to be run is:
pageViewController.setViewControllers(varPageVC, direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: nil)
I get an error :
test.swift:31:9: Ambiguous reference to member 'pageViewController(_:viewControllerBefore:)'.
I do not know how to interpret this error and move forward. The error is triggered in the test.swift, where a timer calls a function that tries to advance the slide. Advise is appreciated. If I am doing it wrong, please point me in the appropriate direction.
The landing page has a button, that opens a ViewController testVC. I have 2 files, test.swift and alphabetItemController.swift. The storyboard has, in addition to the landing page ViewController, a PageViewController called alphabetPVC, a ViewController called alphabetVC and a ViewController called TestVC.
Here is the code for alphabetItemController.swift ...
import UIKit
class alphabetItemController: UIViewController {
#IBOutlet weak var contentImageView2: UIImageView!
#IBOutlet weak var contentWordPn: UILabel!
var itemIndex: Int = 0
var imageName: String = ""
var wordPN: String = ""
var tTime: Timer!
override func viewDidLoad() {
super.viewDidLoad()
contentImageView2!.image = UIImage(named: imageName)
contentWordPn!.text = wordPN
}
}
Here is the code for test.swift ...
import Foundation
import UIKit
class testItemController: UIViewController, UIPageViewControllerDataSource {
var tTime: Timer!
override func viewDidLoad() {
super.viewDidLoad()
createPageViewController()
setupPageControl()
tTime = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(changeSlide), userInfo: nil, repeats: true)
//tTime = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(goToNextPage), userInfo: nil, repeats: true)
}
func changeSlide() {
pageViewController.setViewControllers(varPageVC, direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: nil)
}
// MARK: - Variables
private var varPageVC: UIPageViewController?
private let contentTextWordPN = ["A", "B", "C", "D", "E"]
private let contentCount = 5 //TODO ADJUST THIS FOR EACH COLLECTION
private func createPageViewController() {
let pageController = self.storyboard!.instantiateViewController(withIdentifier: "alphabetPVC") as! UIPageViewController
pageController.dataSource = self
if contentCount > 0 {
let firstController = getItemController(itemIndex: 0)!
let startingViewControllers = [firstController]
pageController.setViewControllers(startingViewControllers, direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
}
varPageVC = pageController
addChildViewController(varPageVC!)
self.view.addSubview(varPageVC!.view)
varPageVC!.didMove(toParentViewController: self)
}
private func setupPageControl() {
let appearance = UIPageControl.appearance()
appearance.pageIndicatorTintColor = UIColor.gray
appearance.currentPageIndicatorTintColor = UIColor.white
appearance.backgroundColor = UIColor.darkGray
}
func pageViewController(_ varPageVC: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let itemController = viewController as! alphabetItemController
if itemController.itemIndex > 0 {
return getItemController(itemIndex: itemController.itemIndex-1)
}
return nil
}
func pageViewController(_ varPageVC: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let itemController = viewController as! alphabetItemController
if itemController.itemIndex+1 < contentCount {
return getItemController(itemIndex: itemController.itemIndex+1)
}
return nil
}
private func getItemController(itemIndex: Int) -> alphabetItemController? {
if itemIndex < contentCount {
let pageItemController = self.storyboard!.instantiateViewController(withIdentifier: "alphabetVC") as! alphabetItemController
pageItemController.itemIndex = itemIndex
pageItemController.imageName = "alphabet_" + String(format: "%02d", (itemIndex + 1)) //alphabet_01
pageItemController.wordPN = contentTextWordPN[itemIndex]
return pageItemController
}
return nil
}
func presentationCountForPageViewController(varPageVC: UIPageViewController) -> Int {
return contentCount
}
func presentationIndexForPageViewController(varPageVC: UIPageViewController) -> Int {
return 0
}
func currentControllerIndex() -> Int {
let pageItemController = self.currentController()
if let controller = pageItemController as? alphabetItemController {
return controller.itemIndex
}
return -1
}
func currentController() -> UIViewController? {
if (self.varPageVC?.viewControllers?.count)! > 0 {
return self.varPageVC?.viewControllers![0]
}
return nil
}
}
extension UIPageViewController {
func goToNextPage(animated: Bool = true) {
guard let currentViewController = self.viewControllers?.first else { return }
guard let nextViewController = dataSource?.pageViewController(self, viewControllerAfter: currentViewController) else { return }
setViewControllers([nextViewController], direction: .forward, animated: animated, completion: nil)
}
func goToPreviousPage(animated: Bool = true) {
guard let currentViewController = self.viewControllers?.first else { return }
guard let previousViewController = dataSource?.pageViewController(self, viewControllerBefore: currentViewController) else { return }
setViewControllers([previousViewController], direction: .reverse, animated: animated, completion: nil)
}
}
There is even an extension UIPageViewController, but I do not know how to call the goToNextPage function.
I ended up changing the changeSlide() function... I had the next slide function in the extension already, and only the syntax to call it was eluding me... I found some examples on SO and used them as references:
func changeSlide() {
varPageVC?.goToNextPage()
}

PageViewController after go to View Controller

I have a pageViewController with 3 viewControllers which is embedded in a view of a viewcontroller.
i am setting the view controllers programatically:
lazy var vcArr: [UIViewController] = {
return [self.vcInstance(name: "vc1"),
self.vcInstance(name: "vc2"),
self.vcInstance(name: "vc3"),
]
}()
i am programatically setting the number of pages to 4
let pageController = UIPageControl.appearance()
pageController.numberOfPages = 4
what i want to happen is that if the user tries to swipe right from the 3rd page it will segue to a signup viewController.
I'm currently trying to achieve this in the viewcontroller after function testing for it the next item is greater than or equal to the total count.
public func pageViewController(_ pageViewController: UIPageViewController,
viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = vcArr.index(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
if nextIndex >= vcArr.count {
infoClick()
return nil
} else {
guard nextIndex < vcArr.count else {
return self.vcArr.last
}
guard self.vcArr.count > nextIndex else {
return nil
}
return self.vcArr[nextIndex]
}
}
with this test the way it is sometimes it stops on page 3 and then when swiped right it will segue off with my function infoClick(). however somethings it goes right off when it hits the 3rd page as you would think because its > or = the number of pages which is 3.
when i change this to just > it doesn't display anything on the third page.
I've searched heaps for a way around this but to no avail. does anyone have any ideas how to achieve this?
attaching entire class below:
import UIKit
import Parse
class pageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
#IBOutlet var createAccountBarButton: UIBarButtonItem!
lazy var vcArr: [UIViewController] = {
return [self.vcInstance(name: "vc1"),
self.vcInstance(name: "vc2"),
self.vcInstance(name: "vc3"),
]
}()
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
//---------------------------------------------- autoLogin
/// temporary location, needs to be launched during the loading screen
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
// if (PFUser.current() != nil) {
// let vc = self.storyboard!.instantiateViewController(withIdentifier: "PackViewController")
// self.present(vc, animated: true, completion: nil)
// if (PFUser.current() != nil) {
// let tbc = self.storyboard!.instantiateViewController(withIdentifier: "MyTabController") as! UITabBarController
// tbc.selectedIndex = 1
// self.present(tbc, animated: true, completion: nil)
// }
}
//---------------------------------------------- set the viewcontrollwe instance
private func vcInstance(name: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: name)
}
//---------------------------------------------- set the direction and first page of the page controller
override func viewDidLoad() {
super.viewDidLoad()
self.tabBarController?.tabBar.isHidden = true
let pageController = UIPageControl.appearance()
pageController.pageIndicatorTintColor = UIColor.lightGray
pageController.currentPageIndicatorTintColor = GeneralFunctions.UIColorFromHEX(hexValue: 0xbb0d2a)
pageController.backgroundColor = UIColor.clear
pageController.bounds = CGRect(x: 0, y: 0, width: 0, height: 0)
pageController.numberOfPages = 4
//GeneralFunctions.commonButtonSettings(buttonName: signUpButton, hexValue: 0x0c1537)
self.dataSource = self
self.dataSource = self
if let firstVC = vcArr.first {
setViewControllers([firstVC], direction: .forward, animated: true, completion: nil)
}
}
//---------------------------------------------- page view controller before settings
public func pageViewController(_ pageViewController: UIPageViewController,
viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = vcArr.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
if previousIndex < 0 {
return nil
} else {
guard previousIndex >= 0 else {
return self.vcArr.last
}
guard self.vcArr.count > previousIndex else {
return nil
}
return self.vcArr[previousIndex]
}
}
//---------------------------------------------- page view controller after settings
public func pageViewController(_ pageViewController: UIPageViewController,
viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = vcArr.index(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
if nextIndex >= vcArr.count {
infoClick()
return nil
} else {
guard nextIndex < vcArr.count else {
return self.vcArr.last
}
guard self.vcArr.count > nextIndex else {
return nil
}
return self.vcArr[nextIndex]
}
}
//---------------------------------------------- presentation count
public func presentationCount(for pageViewController: UIPageViewController) -> Int {
return self.vcArr.count
}
//---------------------------------------------- presentation index
public func presentationIndex(for pageViewController: UIPageViewController) -> Int {
guard let firstViewController = viewControllers?.first,
let firstViewControllerIndex = vcArr.index(of: firstViewController) else {
return 0
}
return firstViewControllerIndex
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//---------------------------------------------- launch the new view controller - still launching before swipped to 4th window sometimes
// not sure if this is the best way to do this need to look at this a bit more
func infoClick() {
let storyboard: UIStoryboard = UIStoryboard (name: "Main", bundle: nil)
let vc: SignupViewController = storyboard.instantiateViewController(withIdentifier: "SignupViewController") as! SignupViewController
let currentController = getCurrentViewController()
currentController?.present(vc, animated: false, completion: nil)
}
func getCurrentViewController() -> UIViewController? {
if let rootController = UIApplication.shared.keyWindow?.rootViewController {
var currentController: UIViewController! = rootController
while( currentController.presentedViewController != nil ) {
currentController = currentController.presentedViewController
}
return currentController
}
return nil
}
}

Add initial note

I am looking at adding an inital note to the note page within my app. this is so that when people click to the notes part there will be some detail on how to use it rather than just a big empty screen. I have no idea where to implement this though. Could you please help, below is the page where it talks about the dictionaries.
import UIKit
import MessageUI
class DetailViewController: UIViewController, MFMailComposeViewControllerDelegate, UITextViewDelegate {
#IBOutlet weak var tView: UITextView!
#IBAction func BarButton(sender: UIBarButtonItem) {
let textToShare = ""
if let myWebsite = NSURL(string: "")
{
let objectsToShare = [textToShare, myWebsite]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
self.presentViewController(activityVC, animated: true, completion: nil)
}
OpenMail()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tView.text = (allNotes[currentNoteIndex] as Note).note
tView.becomeFirstResponder()
// Set controller as swipe gesture recogniser, to allow keyboard dismissal for text box
var swipe: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "dismissKeyboard")
swipe.direction = UISwipeGestureRecognizerDirection.Down
self.view.addGestureRecognizer(swipe)
self.tView.delegate = self
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if tView.text == "" {
allNotes.removeAtIndex(currentNoteIndex)
}
else {
(allNotes[currentNoteIndex] as Note).note = tView.text
}
Note.saveNotes()
noteTable?.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func configuredMailComposeViewController() -> MFMailComposeViewController {
// Open mail controller on screen and prepare with preset values.
let mailComposerVC = MFMailComposeViewController()
var MessageText: String!
MessageText = tView.text
mailComposerVC.mailComposeDelegate = self
mailComposerVC.setToRecipients([""])
mailComposerVC.setSubject("")
mailComposerVC.setMessageBody(MessageText, isHTML: false)
return mailComposerVC
}
func showSendMailErrorAlert() {
// Alert user to email error
let sendMailErrorAlert = UIAlertView(title: "Could Not Send Email", message: "Your device could not send e-mail. Please check e-mail configuration and try again.", delegate: self, cancelButtonTitle: "OK")
sendMailErrorAlert.show()
}
// MARK: MFMailComposeViewControllerDelegate Method
func mailComposeController(controller: MFMailComposeViewController!, didFinishWithResult result: MFMailComposeResult, error: NSError!) {
controller.dismissViewControllerAnimated(true, completion: nil)
}
func OpenMail() {
//Function to open mail composer on screen
let mailComposeViewController = configuredMailComposeViewController()
if MFMailComposeViewController.canSendMail() {
self.presentViewController(mailComposeViewController, animated: true, completion: nil)
} else {
self.showSendMailErrorAlert()
}
}
func dismissKeyboard() {
// Dismiss keyboard for textfield
self.tView.resignFirstResponder()
}
}
note.swift
import UIKit
var allNotes:[Note] = []
var currentNoteIndex:NSInteger = -1
var noteTable:UITableView?
let KAllNotes:String = "notes"
class Note: NSObject {
var date:String
var note:String
override init() {
date = NSDate().description
note = ""
}
func dictionary() -> NSDictionary {
return ["note":note, "date":date]
}
class func saveNotes() {
var aDictionaries:[NSDictionary] = []
for (var i:NSInteger = 0; i < allNotes.count; i++) {
aDictionaries.append(allNotes[i].dictionary())
}
NSUserDefaults.standardUserDefaults().setObject(aDictionaries, forKey: KAllNotes)
// aDictionaries.writeToFile(filePath(), atomically: true)
}
class func loadnotes() {
allNotes.removeAll(keepCapacity: true)
var defaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()
var savedData:[NSDictionary]? = defaults.objectForKey(KAllNotes) as? [NSDictionary]
// var savedData:NSArray? = NSArray(contentsOfFile: filePath())
if let data:[NSDictionary] = savedData {
for (var i:NSInteger = 0; i < data.count; i++) {
var n:Note = Note()
n.setValuesForKeysWithDictionary(data[i] as [NSObject : AnyObject])
allNotes.append(n)
}
}
}
class func filePath() -> String {
var d:[String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true) as? [String]
if let directories:[String] = d {
var docsDirectory:String = directories[0]
var path:String = docsDirectory.stringByAppendingPathComponent("\(KAllNotes).notes")
return path;
}
return ""
}
}
Thanks in advance
Sam
Add an NSUserDefault boolean that stores whether or not the initial note should be shown, e.g. that the app has been launched for the first time. Then load an initial note accordingly. When a note is added or the initial note is deleted, then change the boolean accordingly so the initial note doesn't show up next time.
You could also initialize your database with an initial note. Not clear from your code how the notes are saved, but this approach would probably rely on the NSUserDefault approach above, except it could be done in the AppDelegate or something.
example:
let InitialSetupComplete = "InitialSetupComplete" // Note: I would define this at the top of a file
let defaults = NSUserDefaults.standardUserDefaults()
if defaults.boolForKey(InitialSetupComplete) {
// Show initial note
}
// Later on when the note is deleted, or modified (or immediately after initial note loaded into the database, see below)
defaults.setBool(true, forKey: InitialSetupComplete)
Would be easier/cleaner just to initialize your database with the initial note in the app delegate (e.g. call within applicationDidFinishLaunching), so your view controller doesn't have to figure this out. Similar code, except you would use setBool right away after the initial note has been saved to the database. I don't know anything about your database from the question, so can't really provide a more detailed example than this. Hope this helps.

Resources