UITabbar Image Not Updating - ios

i want to update image of uitabbar programmatically but it's not updating when i update the image
looks duplicate ???
here is the answer i already tried but no success
UITabBarItem does not update image
UITabBar not showing selected item images in ios 7
how to programmatically change the tabbarItem's image
https://www.appcoda.com/ios-programming-how-to-customize-tab-bar-background-appearance/
Changing tab bar item image and text color iOS
okay now here is my code for customTabbar
// CustomTabBarViewController.swift
// CustomTabBar
import UIKit
class CustomTabBarViewController: UITabBarController, CustomTabBarDataSource, CustomTabBarDelegate, UITabBarControllerDelegate , UISearchBarDelegate, UISearchDisplayDelegate {
var searchController: UISearchController!
let searchBar = UISearchBar()
var btnBarBadge : MJBadgeBarButton!
var btnBar : MJBadgeBarButton!
// #IBOutlet weak var menuButton: UIBarButtonItem!
// MARK: Properties
var meals = [CatModel]()
func onBagdeButtonClick() {
print("button Clicked \(self.btnBarBadge.badgeValue)")
}
func onBarCodeButtonClick() {
self.title = Localization("Categories")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let subContentsVC = storyboard.instantiateViewController(withIdentifier: "Stores") as! Stores
self.navigationController?.pushViewController(subContentsVC, animated: true)
}
func buttonClicked(_ sender: AnyObject?) {
var countt = Int(Constants.cartCount)
if(countt == nil){
countt = 0
}
if(countt!<1){
let alert = UIAlertController(title: Localization("Warning"), message:Localization("YourCartisEmpty"), preferredStyle: .alert)
alert.addAction(UIAlertAction(title: Localization("Ok"), style: .default) { _ in })
self.present(alert, animated: true){}
}else{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let subContentsVC = storyboard.instantiateViewController(withIdentifier: "Cart") as! Cart
self.navigationController?.pushViewController(subContentsVC, animated: true)
}
}
func searchBarSearchButtonClicked( _ searchBar: UISearchBar)
{
print(searchBar.text ?? "this is value")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let subContentsVC = storyboard.instantiateViewController(withIdentifier: "SearchProduct") as! SearchProduct
subContentsVC.stringPassed = searchBar.text!
self.navigationController?.pushViewController(subContentsVC, animated: true)
}
func actOnSpecialNotificationon() {
searchBar.placeholder = Localization("Search")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.tabBar.isHidden = true
self.selectedIndex = 1
self.delegate = self
searchBar.sizeToFit()
searchBar.delegate = self
self.title = Localization("Categories")
searchBar.placeholder = Localization("Search")
searchBar.tintColor = .black
navigationItem.titleView = searchBar
NotificationCenter.default.addObserver(self, selector: #selector(CustomTabBarViewController.actOnSpecialNotificationon), name: NSNotification.Name(rawValue: mySpecialNotificationKey), object: nil)
let customTabBar = CustomTabBar(frame: self.tabBar.frame)
customTabBar.datasource = self
customTabBar.delegate = self
customTabBar.setup()
self.view.addSubview(customTabBar)
let customButton = UIButton(type: UIButtonType.custom)
customButton.frame = CGRect(x: 0, y: 0, width: 5.0, height: 35.0)
customButton.addTarget(self, action: #selector(self.onBagdeButtonClick), for: .touchUpInside)
customButton.setImage(UIImage(named: "Cart"), for: .normal)
let barcodeButton = UIButton(type: UIButtonType.custom)
barcodeButton.frame = CGRect(x: 0, y: 0, width: 35.0, height: 35.0)
barcodeButton.addTarget(self, action: #selector(self.onBarCodeButtonClick), for: .touchUpInside)
barcodeButton.setImage(UIImage(named: "edit_location"), for: .normal)
self.btnBarBadge = MJBadgeBarButton()
self.btnBar = MJBadgeBarButton()
self.btnBarBadge.setup(customButton: customButton)
self.btnBarBadge.removeBadge()
self.btnBar.setup(customButton: barcodeButton)
self.btnBar.removeBadge()
self.btnBarBadge.badgeValue = "0"
self.btnBarBadge.badgeOriginX = 2.0
self.btnBarBadge.badgeOriginY = -4
self.navigationItem.rightBarButtonItem = self.btnBarBadge
self.navigationItem.rightBarButtonItems = [self.btnBarBadge,self.btnBar]
customButton.addTarget(self, action: #selector(CustomTabBarViewController.buttonClicked(_:)), for: .touchUpInside)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.setNavigationBarItem()
self.btnBarBadge.badgeValue = Constants.cartCount
}
// MARK: - CustomTabBarDataSource
func tabBarItemsInCustomTabBar(_ tabBarView: CustomTabBar) -> [UITabBarItem] {
return tabBar.items!
}
// MARK: - CustomTabBarDelegate
func didSelectViewController(_ tabBarView: CustomTabBar, atIndex index: Int) {
if(index == 0){
self.openLeftMenu()
}else{
self.selectedIndex = index
}
for loop in 0..<(self.tabBar.items?.count)!{
let barbutton = self.tabBar.items![loop]
if(index == loop){
barbutton.image = self.updateImageColor(origImage: barbutton.image!, color: .green)
}else{
barbutton.image = self.updateImageColor(origImage: barbutton.image!, color: .lightGray)
}
}
}
func updateImageColor(origImage:UIImage,color:UIColor)->UIImage{
let tintedImage = origImage.withRenderingMode(.alwaysOriginal)
let imageview = UIImageView(image: tintedImage)
imageview.tintColor = color
return imageview.image!
}
// MARK: - UITabBarControllerDelegate
func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return CustomTabAnimatedTransitioning()
}
}
here is the code for CustomTabBar.swift
//
// CustomTabBar.swift
// CustomTabBar
//
import UIKit
protocol CustomTabBarDataSource {
func tabBarItemsInCustomTabBar(_ tabBarView: CustomTabBar) -> [UITabBarItem]
}
protocol CustomTabBarDelegate {
func didSelectViewController(_ tabBarView: CustomTabBar, atIndex index: Int)
}
class CustomTabBar: UIView {
var datasource: CustomTabBarDataSource!
var delegate: CustomTabBarDelegate!
var tabBarItems: [UITabBarItem]!
var customTabBarItems: [CustomTabBarItem]!
var tabBarButtons: [UIButton]!
var initialTabBarItemIndex: Int!
var selectedTabBarItemIndex: Int!
var slideMaskDelay: Double!
var slideAnimationDuration: Double!
var tabBarItemWidth: CGFloat!
var leftMask: UIView!
var rightMask: UIView!
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.white
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setup() {
// get tab bar items from default tab bar
tabBarItems = datasource.tabBarItemsInCustomTabBar(self)
customTabBarItems = []
tabBarButtons = []
initialTabBarItemIndex = 1
selectedTabBarItemIndex = initialTabBarItemIndex
slideAnimationDuration = 0.6
slideMaskDelay = slideAnimationDuration / 2
let containers = createTabBarItemContainers()
createTabBarItemSelectionOverlay(containers)
createTabBarItemSelectionOverlayMask(containers)
createTabBarItems(containers)
}
func createTabBarItemSelectionOverlay(_ containers: [CGRect]) {
let activeColor = UIColor(red: 109/255, green: 187/255, blue: 16/255, alpha: 1.0)
let overlayColors = [activeColor, activeColor, activeColor, activeColor,activeColor]
for index in 0..<tabBarItems.count {
let container = containers[index]
let view = UIView(frame: container)
let selectedItemOverlay = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height))
selectedItemOverlay.backgroundColor = overlayColors[index] //.clear
view.addSubview(selectedItemOverlay)
tabBarItems[index].selectedImage = updateImageColor(origImage: tabBarItems[index].image!, color: .green)
self.addSubview(view)
}
}
func updateImageColor(origImage:UIImage,color:UIColor)->UIImage{
let tintedImage = origImage.withRenderingMode(.alwaysTemplate)
let imageview = UIImageView(image: tintedImage)
imageview.tintColor = color
return imageview.image!
}
func createTabBarItemSelectionOverlayMask(_ containers: [CGRect]) {
tabBarItemWidth = self.frame.width / CGFloat(tabBarItems.count)
let leftOverlaySlidingMultiplier = CGFloat(initialTabBarItemIndex) * tabBarItemWidth
let rightOverlaySlidingMultiplier = CGFloat(initialTabBarItemIndex + 1) * tabBarItemWidth
leftMask = UIView(frame: CGRect(x: 0, y: 0, width: leftOverlaySlidingMultiplier, height: self.frame.height))
leftMask.backgroundColor = UIColor.white
rightMask = UIView(frame: CGRect(x: rightOverlaySlidingMultiplier, y: 0, width: tabBarItemWidth * CGFloat(tabBarItems.count - 1), height: self.frame.height))
rightMask.backgroundColor = UIColor.white
self.addSubview(leftMask)
self.addSubview(rightMask)
}
func createTabBarItems(_ containers: [CGRect]) {
var index = 0
for item in tabBarItems {
let container = containers[index]
let customTabBarItem = CustomTabBarItem(frame: container)
customTabBarItem.setup(item)
self.addSubview(customTabBarItem)
customTabBarItems.append(customTabBarItem)
let button = UIButton(frame: CGRect(x: 0, y: 0, width: container.width, height: container.height))
button.addTarget(self, action: #selector(CustomTabBar.barItemTapped(_:)), for: UIControlEvents.touchUpInside)
customTabBarItem.addSubview(button)
tabBarButtons.append(button)
index += 1
}
self.customTabBarItems[initialTabBarItemIndex].iconView.tintColor = .green //UIColor.white
}
func createTabBarItemContainers() -> [CGRect] {
var containerArray = [CGRect]()
// create container for each tab bar item
for index in 0..<tabBarItems.count {
let tabBarContainer = createTabBarContainer(index)
containerArray.append(tabBarContainer)
}
return containerArray
}
func createTabBarContainer(_ index: Int) -> CGRect {
let tabBarContainerWidth = self.frame.width / CGFloat(tabBarItems.count)
let tabBarContainerRect = CGRect(x: tabBarContainerWidth * CGFloat(index), y: 0, width: tabBarContainerWidth, height: self.frame.height)
return tabBarContainerRect
}
func animateTabBarSelection(from: Int, to: Int) {
let overlaySlidingMultiplier = CGFloat(to - from) * tabBarItemWidth
let leftMaskDelay: Double
let rightMaskDelay: Double
if overlaySlidingMultiplier > 0 {
leftMaskDelay = slideMaskDelay
rightMaskDelay = 0
}
else {
leftMaskDelay = 0
rightMaskDelay = slideMaskDelay
}
UIView.animate(withDuration: slideAnimationDuration - leftMaskDelay, delay: leftMaskDelay, options: UIViewAnimationOptions(), animations: {
self.leftMask.frame.size.width += overlaySlidingMultiplier
}, completion: nil)
UIView.animate(withDuration: slideAnimationDuration - rightMaskDelay, delay: rightMaskDelay, options: UIViewAnimationOptions(), animations: {
self.rightMask.frame.origin.x += overlaySlidingMultiplier
self.rightMask.frame.size.width += -overlaySlidingMultiplier
self.customTabBarItems[from].iconView.tintColor = UIColor.black
self.customTabBarItems[to].iconView.tintColor = UIColor.white
}, completion: nil)
}
func barItemTapped(_ sender : UIButton) {
let index = tabBarButtons.index(of: sender)!
//tabBarItems[index].selectedImage = nil
//tabBarItems[index].image = nil
// tabBarItems[index].image = UIImage(named: "Home_Tab");
animateTabBarSelection(from: selectedTabBarItemIndex, to: index)
selectedTabBarItemIndex = index
delegate.didSelectViewController(self, atIndex: index)
}
}
when i try changing image nothing happen
tabBarItems[index].image = UIImage(named: "Home_Tab")
tabBarItems[index].image = UIImage(named: "Home_Tab")?.withRenderingMode(.alwaysOriginal)
Same for selected image
it works when i set image in createTabBarItemSelectionOverlay method
i tried removing image and setting it again but no success
also tried to set image with .alwaysOriginal render mode no luck
please help where am i doing wrong ??
Thank you...little help will be appriciated

Related

use class in swiftui

I have these two classes which are for having the custom tapbar, I would like to use them in swiftUI how can I do? I used these wrappers but once implemented the class in the ContentView does not appear to me
I would like to do everything in swiftUI so I would prefer not to use storyboards in the implementation. it's possible ?
//SwiftUI class. I want to use this view already done in SwiftUI
HStack {
SHCircleBarControllerView()
SHCircleBarView()
}
//Class Swift 4
import UIKit
import SwiftUI
struct SHCircleBarControllerView : UIViewControllerRepresentable {
typealias UIViewControllerType = SHCircleBarController
func makeCoordinator() -> SHCircleBarControllerView.Coordinator {
Coordinator(self)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<SHCircleBarControllerView>) -> SHCircleBarController {
return SHCircleBarController()
}
func updateUIViewController(_ uiViewController: SHCircleBarController, context: UIViewControllerRepresentableContext<SHCircleBarControllerView>) {
}
class Coordinator : NSObject {
var parent : SHCircleBarControllerView
init(_ viewController : SHCircleBarControllerView){
self.parent = viewController
}
}
}
class SHCircleBarController: UITabBarController {
fileprivate var shouldSelectOnTabBar = true
private var circleView : UIView!
private var circleImageView: UIImageView!
open override var selectedViewController: UIViewController? {
willSet {
guard shouldSelectOnTabBar, let newValue = newValue else {
shouldSelectOnTabBar = true
return
}
guard let tabBar = tabBar as? SHCircleBar, let index = viewControllers?.firstIndex(of: newValue) else {return}
tabBar.select(itemAt: index, animated: true)
}
}
open override var selectedIndex: Int {
willSet {
guard shouldSelectOnTabBar else {
shouldSelectOnTabBar = true
return
}
guard let tabBar = tabBar as? SHCircleBar else {
return
}
tabBar.select(itemAt: selectedIndex, animated: true)
}
}
open override func viewDidLoad() {
super.viewDidLoad()
let tabBar = SHCircleBar()
self.setValue(tabBar, forKey: "tabBar")
self.circleView = UIView(frame: .zero)
circleView.layer.cornerRadius = 30
circleView.backgroundColor = .white
circleView.isUserInteractionEnabled = false
self.circleImageView = UIImageView(frame: .zero)
circleImageView.layer.cornerRadius = 30
circleImageView.isUserInteractionEnabled = false
circleImageView.contentMode = .center
circleView.addSubview(circleImageView)
self.view.addSubview(circleView)
let tabWidth = self.view.bounds.width / CGFloat(self.tabBar.items?.count ?? 4)
circleView.frame = CGRect(x: tabWidth / 2 - 30, y: self.tabBar.frame.origin.y - 40, width: 60, height: 60)
circleImageView.frame = self.circleView.bounds
}
open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
circleImageView.image = image(with: self.tabBar.selectedItem?.image ?? self.tabBar.items?.first?.image, scaledTo: CGSize(width: 30, height: 30))
}
private var _barHeight: CGFloat = 74
open var barHeight: CGFloat {
get {
if #available(iOS 11.0, *) {
return _barHeight + view.safeAreaInsets.bottom
} else {
return _barHeight
}
}
set {
_barHeight = newValue
updateTabBarFrame()
}
}
private func updateTabBarFrame() {
var tabFrame = self.tabBar.frame
tabFrame.size.height = barHeight
tabFrame.origin.y = self.view.frame.size.height - barHeight
self.tabBar.frame = tabFrame
tabBar.setNeedsLayout()
}
open override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
updateTabBarFrame()
}
open override func viewSafeAreaInsetsDidChange() {
if #available(iOS 11.0, *) {
super.viewSafeAreaInsetsDidChange()
}
updateTabBarFrame()
}
open override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
guard let idx = tabBar.items?.firstIndex(of: item) else { return }
if idx != selectedIndex, let controller = viewControllers?[idx] {
shouldSelectOnTabBar = false
selectedIndex = idx
let tabWidth = self.view.bounds.width / CGFloat(self.tabBar.items!.count)
UIView.animate(withDuration: 0.3) {
self.circleView.frame = CGRect(x: (tabWidth * CGFloat(idx) + tabWidth / 2 - 30), y: self.tabBar.frame.origin.y - 15, width: 60, height: 60)
}
UIView.animate(withDuration: 0.15, animations: {
self.circleImageView.alpha = 0
}) { (_) in
self.circleImageView.image = self.image(with: item.image, scaledTo: CGSize(width: 30, height: 30))
UIView.animate(withDuration: 0.15, animations: {
self.circleImageView.alpha = 1
})
}
delegate?.tabBarController?(self, didSelect: controller)
}
}
private func image(with image: UIImage?, scaledTo newSize: CGSize) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(newSize, _: false, _: 0.0)
image?.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
You can set up your custom UIViewControllers inside the SHCircleBarController through the viewControllers property.
In SHCircleBarController
open override func viewDidLoad() {
super.viewDidLoad()
...
viewControllers = [ViewController(), ViewController2()]
}
Your other UIViewControllers
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
}
}
class ViewController2: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .blue
}
}
This is the result

Strange UITextField in UINavigationBar constraint issues only on iOS 10 or higher

After I updated my iPhone to iOS 10 I noticed this very strange constraint issue with a UITextField in a UINavigationBar has appeared in my app iOS Tipped. I thought updating my Xcode project to swift 3 would fix it but the problem persists. For some reason this ins't an issue with iOS 9 and lower.
Please download my app Tipped... it's free and you will be able to see
the issue described below.
1: When I launch my app and tap the tab bar to the viewController with the textfield constraint issue in the navigation bar I get this
2: When I press another tab bar option (like the home page) the tap the search tab bar option (navigating back to the page with the issue) I get this
3: Also when I tap one of the segment buttons on the search page with the constraint issue. The constraint issue will reappear and the textfield will go too far to the right.
I have tried the below code to try to fix the problem but nothing seems to be working. Really stuck here any help would be like awesome.
override func viewWillAppear(_ animated: Bool) {
// searchTextField.becomeFirstResponder()
print("viewWillAppear: searchPageViewController")
navigationView.setNeedsLayout()
navigationView.updateConstraintsIfNeeded()
searchTextField.updateConstraints()
searchTextField.setNeedsLayout()
}
Below is the code from the viewcontroller that I am having trouble with.
class SearchPageViewController: UIPageViewController, UISearchBarDelegate, UISearchDisplayDelegate, UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIScrollViewDelegate, UITextFieldDelegate {
//%%% customizeable button attributes
let X_BUFFER:CGFloat = 0.0; //%%% the number of pixels on either side of the segment
let Y_BUFFER:CGFloat = 0.0; //%%% number of pixels on top of the segment
let HEIGHT:CGFloat = 44.0; //%%% height of the segment
//%%% customizeable selector bar attributes (the black bar under the buttons)
let BOUNCE_BUFFER:CGFloat = 10.0; //%%% adds bounce to the selection bar when you scroll
let ANIMATION_SPEED:CGFloat = 0.2; //%%% the number of seconds it takes to complete the animation
let SELECTOR_Y_BUFFER:CGFloat = 40.0; //%%% the y-value of the bar that shows what page you are on (0 is the top)
let SELECTOR_HEIGHT:CGFloat = 4.0; //%%% thickness of the selector bar
let X_OFFSET:CGFloat = 0.0; //%%% for some reason there's a little bit of a glitchy offset. I'm going to look for a better workaround in the future
var navigationView = UIView()
var containerView = UIView()
var buttonText:NSArray = []
var pageScrollView:UIScrollView!
var currentPageIndex:Int!
var selectionBar = UIView()
var buttonOneTap:Bool = false
var buttonTwoTap:Bool = false
fileprivate var _controllerEnum: ControllerEnum = ControllerEnum()
fileprivate var _dict: [UIViewController: ControllerEnum] = [:]
var editView = UIView()
// var delegate: ViewControllerDelegate? = nil
// var userList = NSMutableArray()
// var searchString = String()
// var viewControllerArray:NSMutableArray = NSMutableArray()
var blogSearchCollectionViewController:BlogSearchCollectionViewController!
// var pageViewController: UIPageViewController!
var pageTitles: NSArray!
var pageImages: NSArray!
let searchController = UISearchController(searchResultsController: nil)
#IBOutlet weak var searchBarView: UIView!
#IBOutlet weak var searchTextField: UITextField!
//Stretching the searchTextField full width of navbar
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
widenTextField()
}
func widenTextField() {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: 8, height: 0))
self.searchTextField.leftView = paddingView
self.searchTextField.leftViewMode = .always
let paddingViewRight = UIView(frame: CGRect(x: 0, y: 0, width: 8, height: 0))
self.searchTextField.rightView = paddingViewRight
self.searchTextField.rightViewMode = .always
searchBarView.frame = CGRect(x: 16, y: 5, width: self.view.frame.width, height: 34)
// var frame:CGRect = self.searchTextField.frame
// frame.size.width = self.view.frame.width
// self.searchTextField.frame = CGRectMake(16, 5, self.view.frame.width, 33)
}
// TextFieldDelegates
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// textField.resignFirstResponder()
handleTap(editView)
if currentPageIndex == 0 {
let vc = self.viewControllerAtIndex(currentPageIndex) as BlogSearchCollectionViewController
// vc.loadUsers(textField.text.lowercaseString)
vc.searchText = textField.text!.lowercased()
vc.loadObjects()
vc.showActivityIndicator()
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: false, completion: nil)
} else if currentPageIndex == 1 {
let vc = self.viewControllerAtIndexTwo(currentPageIndex) as PhotoSearchController
vc.search(textField.text!.lowercased())
vc.showActivityIndicator()
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: false, completion: nil)
}
return true
}
// var lastTextFieldEdit:String!
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
showEditView()
if let text = textField.text {
if text.characters.count > 0 {
DispatchQueue.main.async{
textField.selectAll(nil)
}
}
}
searchTextField.textAlignment = NSTextAlignment.left
return true
}
func textFieldDidBeginEditing(_ textField: UITextField) {
print(textField)
}
override func viewWillAppear(_ animated: Bool) {
// searchTextField.becomeFirstResponder()
print("viewWillAppear: searchPageViewController")
}
override func viewDidAppear(_ animated: Bool) {
}
override func viewDidLoad() {
super.viewDidLoad()
self.setupSegmentButtons()
self.setupPage()
currentPageIndex = 0
// self.navigationItem.titleView = searchTextField
}
//Mark: SearchBar stuff
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
// searchController.searchBar.showsCancelButton = true
return true
}
func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
searchController.searchBar.showsCancelButton = true
// for subView in searchController.view.subviews {
// if let dimView = subView as? UIView {
// dimView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
// }
// }
return true
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
for subView in searchController.view.subviews {
}
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
print("hithere")
searchController.searchBar.showsCancelButton = true
// searchController.dimsBackgroundDuringPresentation = false
print("searchController.view.subviews1: - \(searchController.searchBar.subviews)")
for subView in searchController.view.subviews {
print("searchController.view.subviews2: - \(searchController.view.subviews)")
if let dimView = subView as? UIView {
dimView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.0)
}
}
// searchController.dismissViewControllerAnimated(true, completion: nil)
if currentPageIndex == 0 {
let vc = self.viewControllerAtIndex(currentPageIndex) as BlogSearchCollectionViewController
// vc.loadUsers(searchBarString.lowercaseString)
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: false, completion: nil)
} else if currentPageIndex == 1 {
let vc = self.viewControllerAtIndexTwo(currentPageIndex) as PhotoSearchController
vc.search(searchBarString.lowercased())
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: false, completion: nil)
}
}
var searchBarString:String!
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchController.searchBar.showsCancelButton = true
let uiButton = searchController.searchBar.value(forKey: "cancelButton") as! UIButton
uiButton.setTitle("Cancel", for: UIControlState())
uiButton.setTitleColor(UIColor.black, for: UIControlState())
uiButton.titleLabel!.font = UIFont(name: "Helvetica Neue", size: 17)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchBarString = searchText
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func setupSegmentButtons() {
navigationView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: HEIGHT))
navigationView.backgroundColor = UIColor.brown
let numControllers = 2
// if buttonText == NSNotFound {
buttonText = NSArray(objects: "BLOGS", "TIPS")
// }
let buttonOne:UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width/2, height: HEIGHT))
let buttonTwo:UIButton = UIButton(frame: CGRect(x: self.view.frame.size.width/2, y: 0, width: self.view.frame.size.width/2, height: HEIGHT))
navigationView.addSubview(buttonOne)
navigationView.addSubview(buttonTwo)
buttonOne.tag = 0
buttonOne.backgroundColor = UIColor.white
buttonOne.addTarget(self, action: #selector(SearchPageViewController.tapSegmentButtonAction(_:)), for: UIControlEvents.touchUpInside)
buttonOne.setTitle(buttonText[0] as? String, for: UIControlState())
buttonOne.setTitleColor(UIColor.black, for: UIControlState())
buttonOne.titleLabel!.font = UIFont(name: "Interstate-Bold", size: 17)!
buttonTwo.tag = 1
buttonTwo.backgroundColor = UIColor.white
buttonTwo.addTarget(self, action: #selector(SearchPageViewController.tapSegmentButtonAction(_:)), for: UIControlEvents.touchUpInside)
buttonTwo.setTitle(buttonText[1] as? String, for: UIControlState())
buttonTwo.setTitleColor(UIColor.black, for: UIControlState())
buttonTwo.titleLabel!.font = UIFont(name: "Interstate-Bold", size: 17)
self.view.addSubview(navigationView)
self.setupSelector()
}
func setupSelector() {
selectionBar = UIView(frame: CGRect(x: X_BUFFER-X_OFFSET, y: SELECTOR_Y_BUFFER,width: (self.view.frame.size.width-2*X_BUFFER)/2, height: SELECTOR_HEIGHT))
selectionBar.backgroundColor = UIColor(red: 251/255, green: 73/255, blue: 90/255, alpha: 1.0)
// selectionBar.alpha = 1
navigationView.addSubview(selectionBar)
}
func setupPage() {
// self.navigationItem.titleView = searchTextField
view.backgroundColor = UIColor.white
//TextFieldStuff
searchTextField.delegate = self
searchTextField.placeholder = "Search for blogs"
searchTextField.textAlignment = NSTextAlignment.center
searchTextField.autocorrectionType = .no
//TextField is editing translucent view
editView.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.6)
editView.frame = CGRect(x: 0, /*self.navigationController!.navigationBar.frame.size.height + 20 +*/ y: HEIGHT, width: self.view.frame.size.width, height: self.view.frame.size.height - (self.navigationController!.navigationBar.frame.size.height + 20 + HEIGHT))
self.view.addSubview(editView)
editView.isHidden = true
//tapGesture
editView.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(SearchPageViewController.handleTap(_:)))
editView.addGestureRecognizer(tapGesture)
let pageControl = UIPageControl()
pageControl.backgroundColor = UIColor.white
self.pageTitles = NSArray(objects: "Explore", "Today Widget")
self.pageImages = NSArray(objects: "page1", "page2")
//PageViewControllers
delegate = self
dataSource = self
let vc = self.viewControllerAtIndex(0) as BlogSearchCollectionViewController
// vc.loadUsers("")
vc.searchText = ""
vc.loadObjects()
vc.showActivityIndicator()
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController], direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: nil)
print("pageSetUp:- \(currentPageIndex)")
self.syncScrollView()
}
func handleTap(_ sender : UIView) {
// searchController.resignFirstResponder()
searchTextField.resignFirstResponder()
searchTextField.textAlignment = NSTextAlignment.center
UIView.animate(withDuration: 0.3, animations: { () -> Void in
self.editView.alpha = 0
}, completion: { (success:Bool) -> Void in
if success {
self.editView.isHidden = true
}
})
// UIView.animateWithDuration(0.5, animations: { () -> Void in
// self.editView.alpha = 0
// })
print("Tap Gesture recognized")
}
func showEditView() {
editView.alpha = 0
editView.isHidden = false
UIView.animate(withDuration: 0.3, animations: { () -> Void in
self.editView.alpha = 0.6
})
}
func viewControllerAtIndex(_ index: Int) -> BlogSearchCollectionViewController {
let vc: BlogSearchCollectionViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "BlogSearchCollectionViewController") as! BlogSearchCollectionViewController
return vc
}
func viewControllerAtIndexTwo(_ index: Int) -> PhotoSearchController {
let vc: PhotoSearchController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PhotoSearchController") as! PhotoSearchController
// currentPageIndex = vc.pageIndex
return vc
}
func syncScrollView() {
let x = self.view.subviews
var view:UIView!
for view in x {
if view.isKind(of: UIScrollView.self) {
pageScrollView = view as! UIScrollView
pageScrollView.delegate = self
}
}
}
//%%% when you tap one of the buttons, it shows that page,
//but it also has to animate the other pages to make it feel like you're crossing a 2d expansion,
//so there's a loop that shows every view controller in the array up to the one you selected
//eg: if you're on page 1 and you click tab 3, then it shows you page 2 and then page 3
func tapSegmentButtonAction(_ button:UIButton) {
if buttonOneTap == false && buttonTwoTap == false {
let tempIndex:Int = self.currentPageIndex
//%%% check to see if you're going left -> right or right -> left
// println("buttonTag + tempIndex \(button.tag) \(tempIndex)")
if button.tag > tempIndex {
//%%% scroll through all the objects between the two points
buttonOneTap = true
// var i = tempIndex+1
// for i in stride(from:i, through:(button.tag), by: 1) {
for tempIndex in 0..<button.tag {
// for var i = tempIndex+1; i<=button.tag; i += 1 {
// println(i)
let vc: PhotoSearchController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PhotoSearchController") as! PhotoSearchController
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController] /*[getController(.Debts)!]viewControllerArray.objectAtIndex(i) as! [AnyObject]*/, direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: { (success:Bool) -> Void in
//%%% if the action finishes scrolling (i.e. the user doesn't stop it in the middle),
//then it updates the page that it's currently on
if success == true {
self.buttonOneTap = false
self.updateCurrentPageIndex(1)
// self.searchController.searchBar.placeholder = "Search for tips"
// let txtField = self.navigationItem.titleView as! UITextField
// txtField.placeholder = "Search for tips"
self.searchTextField.placeholder = "Search for tips"
}
})
}
//%%% this is the same thing but for going right -> left
} else if button.tag < tempIndex {
buttonTwoTap = true
// var i = tempIndex+1
// for i in stride(from:i, through:(button.tag), by: -1) {
// for var i = tempIndex-1; i >= button.tag; i -= 1 {
for tempIndex in (0...button.tag).reversed() {
// println(i)
let vc: BlogSearchCollectionViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "BlogSearchCollectionViewController") as! BlogSearchCollectionViewController
// vc.loadUsers("")
vc.searchText = ""
vc.loadObjects()
vc.showActivityIndicator()
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController] /*[getController(_controllerEnum)!] viewControllerArray.objectAtIndex(i) as! [AnyObject]*/, direction: UIPageViewControllerNavigationDirection.reverse, animated: true, completion: { (success:Bool) -> Void in
if success == true {
self.buttonTwoTap = false
self.updateCurrentPageIndex(0)
// self.searchController.searchBar.placeholder = "Search for blogs"
// let txtField = self.navigationItem.titleView as! UITextField
// txtField.placeholder = "Search for blogs"
self.searchTextField.placeholder = "Search for blogs"
}
})
}
}
}
}
func updateCurrentPageIndex(_ newIndex:Int) {
self.currentPageIndex = newIndex
}
//%%% makes sure the nav bar is always aware of what page you're on
//in reference to the array of view controllers you gave
//%%% method is called when any of the pages moves.
var xFromCenter:CGFloat!
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// println(self.currentPageIndex)
//It extracts the xcoordinate from the center point and instructs the selection bar to move accordingly
xFromCenter = self.view.frame.size.width-scrollView.contentOffset.x
print(xFromCenter)
// if xFromCenter > 0 && currentPageIndex == 0 {
// updateCurrentPageIndex(0)
// }
// println(self.currentPageIndex)
var a = X_BUFFER + selectionBar.frame.size.width
var b = CGFloat(currentPageIndex) - X_OFFSET
let xCoor = selectionBar.frame.size.width * CGFloat(self.currentPageIndex)
// println(xCoor)
//%%% checks to see what page you are on and adjusts the xCoor accordingly.
//i.e. if you're on the second page, it makes sure that the bar starts from the frame.origin.x of the
//second tab instead of the beginning
selectionBar.frame = CGRect(x: xCoor - xFromCenter/2, y: selectionBar.frame.origin.y, width: selectionBar.frame.size.width, height: selectionBar.frame.size.height)
}
// MARK: - Page View Controller Data Source
var vcOne:BlogSearchCollectionViewController!
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
var index:Int = currentPageIndex
if index == NSNotFound || index == 0 {
return nil
}
// println(currentPageIndex)
index -= 1
let vcOne = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "BlogSearchCollectionViewController") as! BlogSearchCollectionViewController
// currentPageIndex = vc.pageIndex
// println("actaulIndexBlogSearchCollectionViewController: - \(actaulIndex)")
return vcOne
// return getController(_dict[viewController]!.prevIndex())
}
var vcTwo:PhotoSearchController!
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
var index:Int = currentPageIndex
if index == NSNotFound {
return nil
}
index += 1
if index == buttonText.count {
return nil
}
vcTwo = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PhotoSearchController") as! PhotoSearchController
// currentPageIndex = vc.pageIndex
// if vc.pageIndex == 1 && index == 0 {
// return vc
// }
// println("actaulIndexPhotoSearchController: - \(actaulIndex)")
return vcTwo
// return getController(_dict[viewController]!.nextIndex())
}
var actaulIndex:Int!
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
print("finished: - \(finished)")
print("completed: - \(completed)")
if finished == true && completed == true {
print("currentPageIndex: - \(currentPageIndex)")
if finished == true && completed == true && currentPageIndex == 0 && xFromCenter < 0 {
print("hi")
// searchController.searchBar.placeholder = "Search for tips"
// let txtField = self.navigationItem.titleView as! UITextField
// txtField.placeholder = "Search for tips"
searchTextField.placeholder = "Search for tips"
updateCurrentPageIndex(1)
} else if finished == true && completed == true && currentPageIndex == 1 && xFromCenter > 0 {
print("hi 2")
// searchController.searchBar.placeholder = "Search for blogs"
// let txtField = self.navigationItem.titleView as! UITextField
// txtField.placeholder = "Search for blogs"
searchTextField.placeholder = "Search for blogs"
updateCurrentPageIndex(0)
}
}
}
}
I figured it out. Inside the widen textfield function. I needed to change the following line:
searchBarView.frame = CGRect(x: 16, y: 5, width: self.view.frame.width, height: 34)
to
searchBarView.frame = CGRect(x: 8, y: 5, width: self.view.frame.width - 16, height: 34)

Xcode (Swift 3.0) - How to retain values when switching between controllers in Side bar menu

I have a login screen and upon successful login, I'm passing the object details through a navigation controller to side bar menu controller (topView controller). In side bar menu, I have two options and upon switching from other view controller to top view controller, the values are removed(As per my understanding, I'm passing values from loginVC and it may not be holding those values).
As of now side bar menu transistion is working perfectly fine. But when I switch back from AnotherVC to HomeVC , it is not holding the values which are passed from LoginVC.
Can someone help me to solve this.
Below are my code snippets
StoryBoard:
Code Snippets:
On login button click: (LOGIN VC)
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "loginSuccessIdentifier" {
if let navController = segue.destination as? UINavigationController {
if let destinController = navController.topViewController as? HomeViewController {
destinController.loggedInUser = sender as! UserDetails!
}
}
}
}
HOME VC:
var loggedInUser:UserDetails! //UserDetails class is defined separately. Contains variables like id,firstname, lastname etc. I'm displaying those values on HomeVC
override func viewDidLoad() {
super.viewDidLoad()
addSlideMenuButton()
tokenLbl.adjustsFontSizeToFitWidth = true
nameLbl.adjustsFontSizeToFitWidth = true
idLbl.adjustsFontSizeToFitWidth = true
if(loggedInUser != nil)
{
firstLbl.text = loggedInUser.token
secondLbl.text = loggedInUser.lastname
idLbl.text = String(loggedInUser.agentId)
}
}
SIDEBARMENU VC:
protocol SlideMenuDelegate {
func slideMenuItemSelectedAtIndex(_ index : Int32)
}
class MenuViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tblMenuOptions : UITableView!
#IBOutlet var btnCloseMenuOverlay : UIButton!
var arrayMenuOptions = [Dictionary<String,String>]()
var btnMenu : UIButton!
var delegate : SlideMenuDelegate?
override func viewDidLoad() {
super.viewDidLoad()
tblMenuOptions.tableFooterView = UIView()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
updateArrayMenuOptions()
}
func updateArrayMenuOptions(){
arrayMenuOptions.append(["title":"HOME VC", "icon":"Icon1"])
arrayMenuOptions.append(["title":"ANOTHER VC", "icon":"Icon2"])
tblMenuOptions.reloadData()
}
#IBAction func onCloseMenuClick(_ button:UIButton!){
btnMenu.tag = 0
if (self.delegate != nil) {
var index = Int32(button.tag)
if(button == self.btnCloseMenuOverlay){
index = -1
}
delegate?.slideMenuItemSelectedAtIndex(index)
}
UIView.animate(withDuration: 0.3, animations: { () -> Void in
self.view.frame = CGRect(x: -UIScreen.main.bounds.size.width, y: 0, width: UIScreen.main.bounds.size.width,height: UIScreen.main.bounds.size.height)
self.view.layoutIfNeeded()
self.view.backgroundColor = UIColor.clear
}, completion: { (finished) -> Void in
self.view.removeFromSuperview()
self.removeFromParentViewController()
})
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cellMenu")!
cell.selectionStyle = UITableViewCellSelectionStyle.none
cell.layoutMargins = UIEdgeInsets.zero
cell.preservesSuperviewLayoutMargins = false
cell.backgroundColor = UIColor.clear
let lblTitle : UILabel = cell.contentView.viewWithTag(101) as! UILabel
let imgIcon : UIImageView = cell.contentView.viewWithTag(100) as! UIImageView
imgIcon.image = UIImage(named: arrayMenuOptions[indexPath.row]["icon"]!)
lblTitle.text = arrayMenuOptions[indexPath.row]["title"]!
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let btn = UIButton(type: UIButtonType.custom)
btn.tag = indexPath.row
self.onCloseMenuClick(btn)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayMenuOptions.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1;
}
}
BASE VC: (FOR SLIDE DELEGATE)
class BaseViewController: UIViewController, SlideMenuDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func slideMenuItemSelectedAtIndex(_ index: Int32) {
let topViewController : UIViewController = self.navigationController!.topViewController!
print("View Controller is : \(topViewController) \n", terminator: "")
switch(index){
case 0:
print("HomeVC\n", terminator: "")
self.openViewControllerBasedOnIdentifier("HomeVC")
break
case 1:
print("AnotherVC\n", terminator: "")
self.openViewControllerBasedOnIdentifier("AnotherVC")
break
default:
print("default\n", terminator: "")
}
}
func openViewControllerBasedOnIdentifier(_ strIdentifier:String){
let destViewController : UIViewController = self.storyboard!.instantiateViewController(withIdentifier: strIdentifier)
let topViewController : UIViewController = self.navigationController!.topViewController!
if (topViewController.restorationIdentifier! == destViewController.restorationIdentifier!){
print("Same VC")
} else {
self.navigationController!.pushViewController(destViewController, animated: true)
}
}
//to add slide option button
func addSlideMenuButton(){
let btnShowMenu = UIButton(type: UIButtonType.system)
btnShowMenu.setImage(self.defaultMenuImage(), for: UIControlState())
btnShowMenu.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
btnShowMenu.addTarget(self, action: #selector(BaseViewController.onSlideMenuButtonPressed(_:)), for: UIControlEvents.touchUpInside)
let customBarItem = UIBarButtonItem(customView: btnShowMenu)
self.navigationItem.leftBarButtonItem = customBarItem;
}
func defaultMenuImage() -> UIImage {
var defaultMenuImage = UIImage()
UIGraphicsBeginImageContextWithOptions(CGSize(width: 30, height: 22), false, 0.0)
UIColor.black.setFill()
UIBezierPath(rect: CGRect(x: 0, y: 3, width: 30, height: 1)).fill()
UIBezierPath(rect: CGRect(x: 0, y: 10, width: 30, height: 1)).fill()
UIBezierPath(rect: CGRect(x: 0, y: 17, width: 30, height: 1)).fill()
UIColor.white.setFill()
UIBezierPath(rect: CGRect(x: 0, y: 4, width: 30, height: 1)).fill()
UIBezierPath(rect: CGRect(x: 0, y: 11, width: 30, height: 1)).fill()
UIBezierPath(rect: CGRect(x: 0, y: 18, width: 30, height: 1)).fill()
defaultMenuImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return defaultMenuImage;
}
func onSlideMenuButtonPressed(_ sender : UIButton){
if (sender.tag == 10)
{
// To Hide Menu If it already there
self.slideMenuItemSelectedAtIndex(-1);
sender.tag = 0;
let viewMenuBack : UIView = view.subviews.last!
UIView.animate(withDuration: 0.3, animations: { () -> Void in
var frameMenu : CGRect = viewMenuBack.frame
frameMenu.origin.x = -1 * UIScreen.main.bounds.size.width
viewMenuBack.frame = frameMenu
viewMenuBack.layoutIfNeeded()
viewMenuBack.backgroundColor = UIColor.clear
}, completion: { (finished) -> Void in
viewMenuBack.removeFromSuperview()
})
return
}
sender.isEnabled = false
sender.tag = 10
let menuVC : MenuViewController = self.storyboard!.instantiateViewController(withIdentifier: "MenuViewController") as! MenuViewController
menuVC.btnMenu = sender
menuVC.delegate = self
self.view.addSubview(menuVC.view)
self.addChildViewController(menuVC)
menuVC.view.layoutIfNeeded()
menuVC.view.frame=CGRect(x: 0 - UIScreen.main.bounds.size.width, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height);
UIView.animate(withDuration: 0.3, animations: { () -> Void in
menuVC.view.frame=CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height);
sender.isEnabled = true
}, completion:nil)
}
}
For innocuous data that you only want to hold during a single session, you can store it as an instance property in your App Delegate. To read/write you would just create a new reference to the AppDelegate
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.yourProperty = "saveStuff"
If you want the data to persist, and it is not a large amount of data, try NSUserDefaults. You just have to make sure your objects conform to the NSCoder protocol.
https://developer.apple.com/reference/foundation/userdefaults
If you want the data to persist, and it is not a large amount of data, and the data should be secure, you should use the keychain services.
https://developer.apple.com/reference/security/1658642-keychain_services

How to pass data from Realm to ViewController

I do news app in swift 2.3, xcode 7.3.1. I have Realm DB and data therein from server. I need move to ViewController when I press button and display selected data(news). The button over by my elements of news. How to pass data from selected elements of news to show details on another ViewController?
This is news elements. The button over by elements of with horizontal scrolling:
This is code:
import UIKit
import RealmSwift
let realm4 = try! Realm()
class MainViewController: UIViewController, HorizontalScrollDelegate {
let newsObj = realm4.objects(News)
let nObj = News()
var imageURL: NSURL?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
let hScroll = HorizontalScroll(frame: CGRectMake(0, 0, 380, 160))
hScroll.delegate = self
hScroll.backgroundColor = UIColor.whiteColor()
self.view.addSubview(hScroll)
view.reloadInputViews()
}
func numberOfScrollViewElements() -> Int {
return newsObj.count
}
func elementAtScrollViewIndex(index: Int) -> UIView {
let indexes = newsObj[index]
let view = UIView(frame: CGRectMake(5.0, 0.0, 200.0, 200.0))
var imageView = UIImageView()
let imageLabel = UIImageView()
let newsLable = UILabel()
let button = UIButton()
var image: UIImage? {
get { return imageView.image }
set {
imageView.image = newValue
imageView.sizeToFit()
}
}
newsLable.text = indexes.newsTitle
imageURL = NSURL(string: indexes.newsImage)
if let url = imageURL {
let imageData = NSData(contentsOfURL: url)
if imageData != nil {
image = UIImage(data: imageData!)
}
}
newsLable.lineBreakMode = .ByWordWrapping
newsLable.font = UIFont(name: "Roboto-Bold", size: 18)
newsLable.textColor = UIColor.whiteColor()
newsLable.frame = CGRectMake(7.0, 90.0, 200.0, 50.0)
newsLable.textAlignment = .Left
newsLable.numberOfLines = 0
button.frame = CGRectMake(0.0, 0.0, 200.0, 200.0)
button.addTarget(indexes, action: #selector(tapAction2), forControlEvents: .TouchUpInside)
print("This is 1 nObj \(self.nObj)")
imageLabel.backgroundColor = UIColor.blackColor()
imageLabel.alpha = 0.45
imageLabel.frame = CGRectMake(5.0, 90.0, 200.0, 65.0)
imageView.frame = view.frame
view.addSubview(imageView)
view.addSubview(imageLabel)
view.addSubview(newsLable)
view.addSubview(button)
return view
}
func tapAction2(index: Int) {
print("This is func INDEX \(index)")
//let segueIndex = index
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let newView = storyBoard.instantiateViewControllerWithIdentifier("NewsDetailViewController") as! NewsDetailViewController
newView.modalPresentationStyle = UIModalPresentationStyle.Custom
print("This is nObj \(self.nObj)")
print("This is INDEX \(index)")
newView.newsOfTitle = String(index)
presentViewController(newView, animated: true, completion: nil)
}
}
I try to pass data with index. But in console I have empty data. Maybe problems with Realm.
In console I see
This is INDEX 140659923446288
But I have not this data in my project
This is my Realm DB
As stated in UIButton Class Reference, the signature of an action method takes one of three forms
#IBAction func doSomething()
#IBAction func doSomething(sender: UIButton)
#IBAction func doSomething(sender: UIButton, forEvent event: UIEvent)
but not func doSomething(index: Int).
That's why you get the wrong index in your method.

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