Una aplicación para probar las librerías UIKit y AVFoundation con iOS

BaseViewController.swift

//
//  BaseViewController.swift
//  UIKit component handling
//

import UIKit

class BaseViewController: UIViewController {
    let componentName:String
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
    }
    
    init(_ componentName: String) {
        self.componentName = componentName
        super.init(nibName: nil, bundle: nil)
        self.navigationItem.prompt = componentName
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func appDelegate() -> AppDelegate? {
        guard let app = UIApplication.shared.delegate as? AppDelegate else { return nil }
        return app
    }
}

RootViewController.swift

//
//  ViewController.swift
//  UIKit component handling
//

import UIKit

class RootViewController: UITableViewController, UISearchBarDelegate {
    @IBOutlet var searchBar: UISearchBar!
    
    let componentList : [BaseViewController] = [
        LabelVC("UILabel"),
        ImageViewVC("UIImageView"),
        ToolBarVC("UIToolBar"),
        FirstNavigationBarVC("Navigation Bar"),
        PlayMusicalNotesVC("AVAudioPlayer"),
        WebServiceSchoolsVC("JSON web service"),
        ScrollViewVC("UIScrollView")
        /* ... */
    ]
    
    var filteredData : [BaseViewController]! = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.filteredData = self.componentList
        
        self.searchBar.delegate = self
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.filteredData.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "cell")
        
        cell.textLabel?.text = self.filteredData[indexPath.row].componentName
        
        return cell
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        self.navigationController?.pushViewController(self.filteredData[indexPath.row], animated: true)
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        self.filteredData = searchText.isEmpty ? self.componentList : self.componentList.filter({$0.componentName.contains(searchText)})
        
        tableView.reloadData()
    }
}

AppDelegate.swift

//
//  AppDelegate.swift
//  UIKit component handling
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var effectView: UIView!
    var window: UIWindow?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        return true
    }
    
    func applicationWillResignActive(_ application: UIApplication) {
        makeEffectView()
    }
    
    func applicationDidEnterBackground(_ application: UIApplication) {
    }
    
    func applicationWillEnterForeground(_ application: UIApplication) {
    }
    
    func applicationDidBecomeActive(_ application: UIApplication) {
        removeEffectView()
    }
    
    func applicationWillTerminate(_ application: UIApplication) {
    }
}

extension AppDelegate {
    
    private func makeEffectView() {
        effectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffect.Style.light))
        effectView.frame = CGRect(x:0, y:0, width:UIScreen.main.bounds.size.width, height:UIScreen.main.bounds.size.height)
        self.window?.addSubview(effectView)
    }
    
    private func removeEffectView() {
        if effectView != nil {
            self.effectView.removeFromSuperview()
        }
    }
    
    // Add UIAlertController on UIViewController
    func showMessage(vc: UIViewController, title: String, message: String, actionTitle: String, actionStyle: UIAlertAction.Style) {
        // Create a UIAlertController.
        let alert: UIAlertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        
        // Add an Action of OK.
        alert.addAction(UIAlertAction(title: actionTitle, style: actionStyle, handler: { action in print("Action OK!") }))
        
        // Activate UIAlert.
        vc.present(alert, animated: true, completion: nil)
    }
}

LabelVC.swift

//
//  LabelVC.swift
//  UIKit component handling
//

import UIKit

class LabelVC: BaseViewController {

    lazy var label: UILabel = {
        // Define the size of the label.
        let width: CGFloat = 300
        let height: CGFloat = 100
        
        // Define coordinates to be placed.
        // (center of screen)
        let posX: CGFloat = self.view.bounds.width/2 - width/2
        let posY: CGFloat = self.view.bounds.height/2 - height/2
        
        // Label Create.
        let label: UILabel = UILabel(frame: CGRect(x: posX, y: posY, width: width, height: height))
        
        // Define background color.
        label.backgroundColor = .orange
        
        // Define text color.
        label.textColor = .white
        
        // Define text font.
        label.font = .systemFont(ofSize: 20, weight: .regular)
        
        // Define text of label.
        label.text = "Hello! :)"
        
        // Define count of line.
        // '0' is infinity
        label.numberOfLines = 0
        
        // Round UILabel frame.
        label.layer.masksToBounds = true
        
        // Radius of rounded corner.
        label.layer.cornerRadius = 20.0
        
        // Define shadow color.
        label.shadowColor = .gray
        
        // Define text Alignment.
        // options: .left, .right, .center, .justified, .natural
        label.textAlignment = .center
        
        return label
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Add UILabel to view.
        self.view.addSubview(self.label)
    }
}

ImageViewVC.swift

//
//  ImageViewVC.swift
//  UIKit component handling
//

import UIKit

class ImageViewVC: BaseViewController {
    
    lazy var imageView: UIImageView = {
        // Set the size of UIImageView.
        let width: CGFloat = self.view.bounds.width/2
        let height: CGFloat = 150
        
        // Set x, y of UIImageView.
        let posX: CGFloat = (self.view.bounds.width - width)/2
        let posY: CGFloat = (self.view.bounds.height - height)/2
        
        // Create UIImageView.
        let imageView = UIImageView(frame: CGRect(x: posX, y: posY, width: width, height: height))
        
        // Create UIImage.
        let myImage = UIImage(named: "apple.png")!
        
        // Set the image to UIImageView.
        imageView.image = myImage
        
        return imageView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Add UIImageView to view
        self.view.addSubview(self.imageView)
    }
}

ToolBarVC.swift

//
//  ToolBarVC.swift
//  UIKit component handling
//

import UIKit

class ToolBarVC: BaseViewController {

    private let toolBarHeight: CGFloat = 44
    
    lazy var toolBar: UIToolbar = {
        // Decide the size of the toolbar.
        let tb = UIToolbar(frame: CGRect(x: 0, y: self.view.bounds.size.height - toolBarHeight, width: self.view.bounds.size.width, height: 40.0))
        
        // Determine the position of the toolbar.
        tb.layer.position = CGPoint(x: self.view.bounds.width/2, y: self.view.bounds.height-20.0)
        
        // Decide the color of the toolbar.
        tb.barStyle = .blackTranslucent
        tb.tintColor = .white
        tb.backgroundColor = .black
        
        return tb
    }()
    
    lazy var barButtonGreen: UIBarButtonItem = {
        // Generate button 1.
        return UIBarButtonItem(title: "Green", style:.plain, target: self, action: #selector(onClickBarButton))
    }()
    
    lazy var barButtonBlue: UIBarButtonItem = {
        // Generate button 2.
        return UIBarButtonItem(title: "Blue", style:.plain, target: self, action: #selector(onClickBarButton))
    }()
    
    lazy var barButtonRed: UIBarButtonItem = {
        // Generate button 3.
        return UIBarButtonItem(title: "Red", style:.plain, target: self, action: #selector(onClickBarButton))
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Place the button in the tool bar.
        self.toolBar.items = [self.barButtonGreen, self.barButtonBlue, self.barButtonRed]
        
        // Add UIToolBar on view
        self.view.addSubview(self.toolBar)
    }
    
    // Called when UIBarButtonItem is pressed.
    @objc private func onClickBarButton(sender: UIBarButtonItem) {
        switch sender.title {
            case "Green": self.view.backgroundColor = .green
            case "Blue": self.view.backgroundColor = .blue
            case "Red": self.view.backgroundColor = .red
            default: return
        }
    }
}

Navigation Bar

FirstNavigationBarVC.swift

//
//  FirstNavigationBarVC.swift
//  UIKit component handling
//

import UIKit

class FirstNavigationBarVC: BaseViewController {
    
    lazy var button: UIButton = {
        // Create Button
        let b = UIButton(frame: CGRect(x: 0, y: 0, width: 250, height: 50))
        b.backgroundColor = .orange
        b.layer.masksToBounds = true
        b.setTitle("Go to second view", for: .normal)
        b.layer.cornerRadius = 20.0
        b.layer.position = CGPoint(x: self.view.bounds.width/2, y:200)
        b.addTarget(self, action: #selector(goToNextView), for: .touchDown)
        
        return b
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Define the background color of View.
        self.view.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
        
        // Add button on view
        self.view.addSubview(self.button)
        
        // Create a BarButtonItem.
        let barButton_1 = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(goToPreviousView))
        
        let barButton_2 = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(goToNextView))
        let barButton_3 = UIBarButtonItem(barButtonSystemItem: .fastForward, target: self, action: #selector(goToNextView))
        
        // Set the title.
        self.navigationItem.title = "First View"

        // Place it on the left side of Bar.
        self.navigationItem.setLeftBarButton(barButton_1, animated: true)
        
        // Place multiple on the right side of Bar.
        self.navigationItem.setRightBarButtonItems([barButton_2, barButton_3], animated: true)
    }
    
    // Called when the left bar button is pressed
    @objc private func goToPreviousView(sender: UIBarButtonItem) {
        self.navigationController?.popViewController(animated: true)
    }
    
    // Called when the right bar buttons and the button on the screen are pressed
    @objc private func goToNextView(sender: UIButton) {
        let secondViewController = SecondNavigationBarVC("Second view")
        self.navigationController?.pushViewController(secondViewController, animated: true)
    }
}

SecondNavigationBarVC.swift

//
//  SecondNavigationBarVC.swift
//  UIKit component handling
//

import UIKit

class SecondNavigationBarVC: BaseViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Define the background color of View.
        self.view.backgroundColor = UIColor.green
    }
}

PlayMusicalNotesVC.swift

//
//  PlaySoundVC.swift
//  UIKit component handling
//

import UIKit
import AVFoundation

class PlayMusicalNotesVC: BaseViewController {
    
    var audioPlayer : AVAudioPlayer!
    
    let sounds = ["do", "re", "mi", "fa", "sol", "la", "si", "do2"]
    
    lazy var stackView: UIStackView = {

        let stackView = UIStackView()
        
        stackView.frame = CGRect(x: 0, y: 98, width: self.view.bounds.width, height: self.view.bounds.height - 98)
        stackView.axis = .vertical
        stackView.distribution = .fillEqually
        
        for sound in sounds {
            let button = UIButton()
            
            // Set the background color of the button.
            button.backgroundColor = .white
            button.layer.borderWidth = 1
            button.layer.borderColor = UIColor.black.cgColor
            
            // Set the title (normal).
            button.setTitle(sound, for: .normal)
            button.setTitleColor(.black, for: .normal)
            
            // Set the title (highlighted).
            button.setTitle(sound, for: .highlighted)
            button.setTitleColor(.red, for: .highlighted)
            
            // Add an event.
            button.addTarget(self, action: #selector(onClick), for: .touchDown)
            
            stackView.addArrangedSubview(button)
        }
            
        return stackView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Add UIStackView to view.
        self.view.addSubview(self.stackView)
    }
    
    // Button event.
    @objc private func onClick(_ sender: UIButton) {

        if let soundURL : URL = Bundle.main.url(forResource: sender.currentTitle, withExtension: "mp3") {
            print(soundURL)
            do {
                audioPlayer = try AVAudioPlayer(contentsOf: soundURL)
                audioPlayer.play()
            } catch {
                print(error)
            }
        }
    }
}

WebServiceSchoolsVC

//
//  WebServiceSchoolsVC.swift
//  UIKit component handling
//

import UIKit

class Ciclo : Codable {
    var denominacion:String = ""
    var denominacion_val:String = ""
}

class WebServiceSchoolsVC: BaseViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
    
    // Define the array to use in the Table.
    var ciclos: [Ciclo] = []
    var ciclosFiltrados: [Ciclo] = []
    
    // Define the url to download the data
    let url = URL(string: "https://fernandoruizrico.com:8001/api/getListadoCiclos")
    
    lazy var searchBar: UISearchBar = {
        // Create a search bar.
        let searchBar = UISearchBar()
        searchBar.delegate = self
        searchBar.frame = CGRect(x: 0, y: 98, width: self.view.bounds.width, height: 100)
        
        // Add a shadow.
        searchBar.layer.shadowColor = UIColor.black.cgColor
        searchBar.layer.shadowOpacity = 0.5
        searchBar.layer.masksToBounds = false
        
        // Disable the bookmark button.
        searchBar.showsBookmarkButton = false
        
        // Set bar style to Default.
        searchBar.searchBarStyle = .default
        
        // Set descriptive text.
        searchBar.placeholder = "Buscar"
        
        // Set the color of the cursor and cancel button.
        searchBar.tintColor = .red
        
        // The search result display button is not displayed.
        searchBar.showsSearchResultsButton = false
        
        return searchBar
    }()
    
    lazy var tableView: UITableView = {

        let tableView = UITableView()
        
        tableView.frame = CGRect(x: 0, y: 200, width: self.view.bounds.width, height: self.view.bounds.height)
        
        // Register the Cell name.
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        
        // Set the DataSource.
        tableView.dataSource = self
        
        // Set Delegate.
        tableView.delegate = self
        
        return tableView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        URLSession.shared.dataTask(with: url!) { (data, response, error) in
            do {
                // Decode data
                self.ciclos = try JSONDecoder().decode([Ciclo].self, from: data!)
                self.ciclosFiltrados = self.ciclos
                
                DispatchQueue.main.async {
                    // Add UITableView on view
                    self.view.addSubview(self.searchBar)
                    self.view.addSubview(self.tableView)
                }
            } catch let error {
                print("Error: \(error)")
            }
        }.resume()
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return ciclosFiltrados.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        
        cell.textLabel?.text = self.ciclosFiltrados[indexPath.row].denominacion
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        // Create a UIAlertController.
        let alert: UIAlertController = UIAlertController(title: "Ciclo", message: self.ciclosFiltrados[indexPath.row].denominacion+"\n"+self.ciclosFiltrados[indexPath.row].denominacion_val, preferredStyle: .alert)
        
        // Add an Action of OK.
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        
        present(alert, animated: true, completion: nil)
    }
    
    // Called whenever text is changed
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        self.ciclosFiltrados = searchText.isEmpty ? self.ciclos : self.ciclos.filter({$0.denominacion.contains(searchText)})
        self.tableView.reloadData()
    }
}

ScrollViewVC.swift

//
//  ScrollViewVC.swift
//  UIKit component handling
//

import UIKit

class ScrollViewVC: BaseViewController {
    
    lazy var scrollView: UIScrollView = {
        let scrollView: UIScrollView = UIScrollView()
        
        // Generate ScrollView.
        scrollView.frame = self.view.frame
        
        // Disable ScrollView bounces
        scrollView.bounces = false
        
        // Set the image in UIImage.
        let image = UIImage(named: "vertical.jpeg")!
        
        // Create a UIImageView.
        let imageView = UIImageView()
        
        // Set myImage to the image of imageView.
        imageView.image = image
        
        // Set the value of frame size
        imageView.frame.size = image.size
        
        // Set the aspect ratio of the image.
        imageView.contentMode = .scaleAspectFill
        
        // Add imageView to ScrollView.
        scrollView.addSubview(imageView)
        
        // Set contentSize to ScrollView.
        scrollView.contentSize = imageView.frame.size
        
        return scrollView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Add UIScrollView on view
        self.view.addSubview(self.scrollView)
    }
}

Publicaciones Similares

  • Swift – Clases

    Introducción En este capítulo vamos a ver uno de los conceptos más importantes de la programación orientada a objetos: las clases. Su importancia radica en que todo programador debe diseñar un modelo de datos que soporte el comportamiento que requiere un determinado programa para resolver el problema para el cual es creado y las clases…

  • Swift – Closures

    Introducción Los closures son bloques de código que pueden ser pasados por parámetro a otras funciones a lo largo del código. Una de las ventajas que proveen es que son capaces de capturar y guardar referencias de las constantes y variables del contexto en que son definidos. Las funciones, vistas en una entrada anterior, son…

  • Swift – Funciones

    Concepto de función Al igual que en cualquier otro lenguaje de programación, uno de los puntos básicos que todo desarrollador Swift debe conocer es la manera de trabajar con funciones. Podríamos decir que forma parte del núcleo de un lenguaje y provee un sinfín de beneficios al momento de escribir código claro y mantenible. Una…

  • Swift – Aspectos básicos

    Constantes y variables Cualquier tipo de aplicación necesita poder guardar datos temporalmente en la memoria para poder trabajar con ellos. Las constantes y variables son apartados reservados en la memoria del dispositivo para que podamos acceder a la información que contienen durante la ejecución del programa. En este sentido, se define una variable como un…