Функция общего интерфейса между контроллерами представления

У меня есть некоторые функции, связанные с пользовательским интерфейсом, такие как показ всплывающих окон с предупреждением, отображение индикатора активности в середине экрана или отображение анимации UIView на экране с пользовательским сообщением.
Я хочу использовать затем в нескольких viewControllers (VC1). и VC2 в данном случае), поэтому я не повторяюсь.
Изначально у меня есть следующий код, который работает с обоими VC, наследуемыми от BaseVC, который заботится об этих функциях.
VC1 - это UIViewController со встроенным tablelView, VC2 - это UIViewController со встроенным collectionView.

class VC1: BaseVC {
    func viewDidAppear(animated: Bool) {
        activityIndicatorBegin()
    }

    func btnPressed() {
        activityIndicatorEnd()
    }
}

class VC2: BaseVC {
    func viewDidAppear(animated: Bool) {
        activityIndicatorBegin()
    }

    func btnPressed() {
        activityIndicatorEnd()
    }
}

class BaseVC: UIViewController {

    var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
    var isCustomViewOnScreen = false

    func activityIndicatorBegin() {
        if activityIndicator.isAnimating() == false {
            activityIndicator = UIActivityIndicatorView(frame: CGRectMake(0,0,20,20))
            activityIndicator.center = view.center
            activityIndicator.hidesWhenStopped = true
            activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge
            activityIndicator.color = UIColor.blackColor()
            view.addSubview(activityIndicator)
            activityIndicator.startAnimating()
        }
    }

    func activityIndicatorEnd() {
        if activityIndicator.isAnimating() == true {
            activityIndicator.stopAnimating()
            activityIndicator.removeFromSuperview()
        }
    }

    func animateACustomViewOnScreen() {
        if isCustomViewOnScreen == false {
            // Some animation code 
        }
    }

    func removeCustomView() {
        if isCustomViewOnScreen == true {
            // Some removal code
        }
    }
}

Однако по некоторым причинам я решил сделать VC1 прямым для UITableViewController и VC2 вместо UICollectionViewController.
Это означает, что они больше не могут извлекать из этого BaseVC, который принадлежит к классу UIViewController.

Как я мог сделать так, чтобы оба VC могли все еще достигать тех функций?

4 голоса | спросил user125972 30 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 30 Sep 2016 04:56:13 +0300 2016, 04:56:13

2 ответа


0

Ответ: Protocol Extensions . Вы определяете BaseVC как протокол, а затем расширяете его, добавляя разделяемую логику, которая будет использоваться в классах, реализующих ее:

(BaseVC переименован в ActivityIndicatorDisplaying в приведенном ниже примере.)

protocol ActivityIndicatorDisplaying {

  var activityIndicator: UIActivityIndicatorView { get set }
  var showsCustomView: Bool { get }

  func showActivityIndicator()
  func dismissActivityIndicator()
}

extension ActivityIndicatorDisplaying where Self: UIViewController {

  func showActivityIndicator() {
    if activityIndicator.isAnimating() { return }

    activityIndicator.center = CGPointMake(view.bounds.width / 2, view.bounds.height / 2)
    activityIndicator.hidesWhenStopped = true
    activityIndicator.activityIndicatorViewStyle = .WhiteLarge
    activityIndicator.color = UIColor.blackColor()
    view.addSubview(activityIndicator)
    activityIndicator.startAnimating()
  }

  func dismissActivityIndicator() {
    activityIndicator.stopAnimating()
    activityIndicator.removeFromSuperview()
  }

  func animateACustomViewOnScreen() {
    if !showsCustomView {
      // Some animation code
    }
  }

  func removeCustomView() {
    if showsCustomView {
      // Some removal code
    }
  }
}

class VC1: UITableViewController, ActivityIndicatorDisplaying {

  var activityIndicator = UIActivityIndicatorView()
  var showsCustomView: Bool = false

  override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    showActivityIndicator()
  }

  func btnPressed() {
    dismissActivityIndicator()
  }
}

class VC2: UICollectionViewController, ActivityIndicatorDisplaying {

  var activityIndicator = UIActivityIndicatorView()
  var showsCustomView: Bool = true

  ...
}
ответил ozgur 30 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 30 Sep 2016 05:28:07 +0300 2016, 05:28:07
0

Почему бы не создать подкласс самого UIActivityViewController? Это было бы более логично и чище.

class VC1: UIViewController {
    var customActivityIndicatorView: CustomActivityIndicatorView? = nil

    func viewDidAppear(animated: Bool) {
        if let view = view {
            customActivityIndicatorView = CustomActivityIndicatorView(parentView: view)
        }
    }

    func btnPressed() {
        customActivityIndicatorView?.end()
    }
}

class VC2: UITableViewController {
    var customActivityIndicatorView: CustomActivityIndicatorView? = nil

    func viewDidAppear(animated: Bool) {
        if let view = view {
            customActivityIndicatorView = CustomActivityIndicatorView(parentView: view)
        }
    }

    func btnPressed() {
        customActivityIndicatorView?.end()
    }
}

class CustomActivityIndicatorView: UIActivityIndicatorView {
    var isCustomViewOnScreen = false

    convenience init?(parentView: UIView) {
        if isAnimating == false {
            self.init(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
            center = parentView.center
            hidesWhenStopped = true
            activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
            color = UIColor.black
            parentView.addSubview(self)
            startAnimating()
        } else {
            return nil
        }
    }

    func end() {
        if isAnimating == true {
            stopAnimating()
            removeFromSuperview()
        }
    }

    func animateACustomViewOnScreen() {
        if isCustomViewOnScreen == false {
            // Some animation code
        }
    }

    func removeCustomView() {
        if isCustomViewOnScreen == true {
            // Some removal code
        }
    }
}
ответил Jason Nam 30 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 30 Sep 2016 05:19:55 +0300 2016, 05:19:55

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132