我的问题是我无法从ViewController中的self
获取数据。在调试时,我看到了自己的数据。但我无法得到它。
我试过了self.presenterD.lBEveryOneData[0]
。
我收到此错误Value of type 'LeaderBoardPresenterP' has no member 'lBEveryOneData'
。
这是LeaderBoardPresenter协议。
protocol LeaderBoardPresenterP : class {
var currentTimePeriod : Int {get}
var currentSegment : Int { get}
var numberOfTeam : Int{ get }
var numberOfRowForEveryOne : Int{ get }
func viewDidLoad()
func viewDidAppear()
func viewWillAppear()
func tabBarBtnTap(index : Int)
func segmentBtnTap(index : Int)
func numberOfRowInTeam(section : Int)->(Int)
func configureHeaderView(leaderBoardHeaderView : LeaderBoardHeaderView, section : Int)
func configureTeamCell(cell : LeaderBoardTeamCell, indexPath : IndexPath)
func configureEveryOneCell(cell : LeaderBoardEveryOneCell, row : Int)
func performForLeaderBoardRefresh(successHandler: @escaping(Bool)->(), errorHandler : @escaping()->())
}
这是LeaderBoardPresenter实施
class LeaderBoardPresenterImplimentation : LeaderBoardPresenterP {
fileprivate weak var leaderViewD : LeaderBoardViewP?
fileprivate var time = 2
fileprivate var segment = 4
fileprivate var lBEveryOneData = Array<LeaderBoardModel>()
fileprivate var lBTeamData = Array<Array<LeaderBoardModel>>()
init(leaderBoardVC : LeaderBoardViewP) {
self.leaderViewD = leaderBoardVC
}
//MARK:- LeaderBoardPresenterP
var numberOfTeam : Int{
return lBTeamData.count
}
var currentTimePeriod : Int {
return time
}
var currentSegment : Int{
return segment
}
var numberOfRowForEveryOne : Int{
return self.lBEveryOneData.count
}
func viewDidLoad()
{
leaderViewD?.setUpOnViewDidLoad()
}
func viewWillAppear()
{
leaderViewD?.setUpOnViewWillAppear()
}
func viewDidAppear()
{
LeaderBoardManager.sharedManager.getLeaderBoardDataRequest(successHandler: { _ in
self.buildLeaderBoardDataSet(complitionHandler: { (isSuccess) in
self.leaderViewD?.reloadList(isData: isSuccess)
self.leaderViewD?.showHideProgressView(false)
})
}, errorHandler: { errorString in
self.buildLeaderBoardDataSet(complitionHandler: { (isSuccess) in
self.leaderViewD?.reloadList(isData: isSuccess)
self.leaderViewD?.showHideProgressView(false)
})
})
leaderViewD?.setUpOnViewDidAppear()
}
func numberOfRowInTeam(section : Int)->(Int)
{
return lBTeamData[section].count
}
func tabBarBtnTap(index : Int)
{
self.time = index
self.leaderViewD?.updateTabBarButton()
self.buildLeaderBoardDataSet(complitionHandler: { (isSuccess) in
self.leaderViewD?.reloadList(isData: isSuccess)
self.leaderViewD?.showHideProgressView(false)
})
}
func segmentBtnTap(index: Int) {
self.segment = index
var isData = false
if self.segment == 4
{
isData = self.lBEveryOneData.count > 0 ? true : false
}
else
{
isData = self.lBTeamData.count > 0 ? true : false
}
self.leaderViewD?.reloadList(isData : isData)
}
func configureEveryOneCell(cell : LeaderBoardEveryOneCell, row : Int)
{
let lbM = lBEveryOneData[row]
let name = lbM.firstName + " " + lbM.lastName
cell.displayName(name: name)
cell.displayScore(score: lbM.totalScore.usFormat())
cell.displayPicture(url: lbM.profileImageUrl, defaultImage: "LB_default_user")
cell.displaySubManager(subManager: lbM.teamName)
cell.displayRank(rank: lbM.rank)
}
func configureTeamCell(cell : LeaderBoardTeamCell, indexPath : IndexPath)
{
let lbM = lBTeamData[indexPath.section][indexPath.row]
let name = lbM.firstName + " " + lbM.lastName
cell.displayName(name: name)
cell.displayScore(score: lbM.totalScore.usFormat())
cell.displayPicture(url: lbM.profileImageUrl, defaultImage: "LB_default_user")
cell.displayRank(rank: indexPath.row + 1)
}
func configureHeaderView(leaderBoardHeaderView : LeaderBoardHeaderView, section : Int)
{
let lbM = lBTeamData[section][0]
let headerTitle = lbM.teamName
leaderBoardHeaderView.displayTitle(headerTitle: headerTitle)
}
func performForLeaderBoardRefresh(successHandler: @escaping(Bool) -> (), errorHandler: @escaping () -> ()) {
LeaderBoardManager.sharedManager.getLeaderBoardDataRequest(successHandler: { _ in
self.buildLeaderBoardDataSet(complitionHandler: { (isSuccess) in
self.leaderViewD?.reloadList(isData: isSuccess)
self.leaderViewD?.showHideProgressView(false)
successHandler(isSuccess)
})
}, errorHandler: { errorString in
//self.leaderViewD?.reloadList(isData: isSuccess)
self.leaderViewD?.showHideProgressView(false)
errorHandler()
})
}
//MARK:- Private Method
fileprivate func buildLeaderBoardDataSet(complitionHandler : @escaping (Bool)->())
{
leaderViewD?.showHideProgressView(true)
self.getLeaderBoardDataFromDBAndCreateSet(successHandler: { (isSuccess) in
complitionHandler(isSuccess)
})
}
fileprivate func getLeaderBoardDataFromDBAndCreateSet(successHandler : @escaping (Bool)->())
{
var type = ""
switch self.currentTimePeriod {
case 1:
type = "thisWeek"
break
case 2:
type = "thisMonth"
break
case 3:
type = "overAll"
break
default:
break
}
LeaderBoardManager.sharedManager.retriveLeaderBoard(type) { (response, success) in
if((response) != nil) {
self.lBEveryOneData = response!
self.createGroupDataSet(lbArr: response!)
successHandler(true)
}else{
successHandler(false)
}
}
}
fileprivate func createGroupDataSet(lbArr : Array<LeaderBoardModel>)
{
if lbArr.count > 0 {
var keyArr = [(Int, String, Int, String)]()
for temp in lbArr
{
let temp1 = temp
keyArr.append((temp1.teamId , temp1.teamName, 0, ""))
}
var keySetArr = [(Int, String, Int, String)]()
for item in keyArr {
if !keySetArr.contains(where:{$0 == item})
{
keySetArr.append(item)
}
}
let sortedKeySet = keySetArr.sorted(by: { (a0, a1) -> Bool in
return a0.1.localizedCaseInsensitiveCompare(a1.1) == ComparisonResult.orderedAscending
})
self.lBTeamData.removeAll()
for item in sortedKeySet
{
var leaderBoardDataArr = lBEveryOneData as Array<LeaderBoardModel>
leaderBoardDataArr = leaderBoardDataArr.filter({ (leaderBoardM) -> Bool in
leaderBoardM.teamId == item.0
})
leaderBoardDataArr = leaderBoardDataArr.sorted(by: { (lb1, lb2) -> Bool in
lb1.totalScore > lb2.totalScore
})
if(leaderBoardDataArr.count > 0)
{
lBTeamData.append(leaderBoardDataArr.map{
$0.copy() as! LeaderBoardModel})
}
}
}
}
这是LeaderBoardVC。
import Foundation
class LeaderBoardVC : UIViewController, UIScrollViewDelegate, UITableViewDataSource, UITableViewDelegate, LeaderBoardViewP {
var configurator : LeaderBoardConfiguratorP!
var presenterD : LeaderBoardPresenterP!
//MARK:- Outlets
@IBOutlet weak var contentView : UIView!
@IBOutlet weak var topScrollView : UIView!
@IBOutlet weak var bottomScroll : UIScrollView!
@IBOutlet weak var leaderBoardTV : UITableView!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
@IBOutlet weak var noRecordL : UILabel!
@IBOutlet weak var everyOneBtn : UIButton!
@IBOutlet weak var teamBtn : UIButton!
@IBOutlet weak var weekBtn : UIButton!
@IBOutlet weak var monthBtn : UIButton!
@IBOutlet weak var allTimeBtn : UIButton!
//MARK:- Life cycle
override func viewDidLoad() {
super.viewDidLoad()
configurator.configure(leaderBoardVC: self)
presenterD.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
presenterD.viewWillAppear()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
presenterD.viewDidAppear()
//Download leaderBoard data from server
self.showHideProgressView(true)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
AppDelegate.getSharedInstance().isShowingChallengOnScreen = false
}
//MARK:- Action
@IBAction func tabBarBtnAction(sender : UIButton) {
presenterD.tabBarBtnTap(index: sender.tag)
}
@IBAction func segmentBtnAction(sender : UIButton) {
presenterD.segmentBtnTap(index: sender.tag)
var seletedbutton : UIButton!
var unSeletedbutton : UIButton!
if(sender.tag == 4)
{
seletedbutton = everyOneBtn
unSeletedbutton = teamBtn
}
else if(sender.tag == 5)
{
seletedbutton = teamBtn
unSeletedbutton = everyOneBtn
}
seletedbutton.setTitleColor(UIColor.white, for: UIControlState.normal)
seletedbutton.backgroundColor = kFYNavigationBarColor
seletedbutton.layer.cornerRadius = 8.0
unSeletedbutton.setTitleColor(kFYNavigationBarBelowColor, for: UIControlState.normal)
unSeletedbutton.backgroundColor = UIColor.clear
unSeletedbutton.layer.cornerRadius = 0.0
}
//MARK:- LeaderBoardView
func setUpOnViewDidLoad()
{
self.navigationController!.navigationBar.topItem!.title = ""
self.navigationItem.title = "LEADERBOARD"
//Add refresh control on tableview
let refreshControl: UIRefreshControl = {
let refreshControl = UIRefreshControl()
refreshControl.tintColor = kFYNavigationBarColor
refreshControl.addTarget(self, action: #selector(self.refreshAction(refreshControl:)), for: UIControlEvents.valueChanged)
return refreshControl
}()
self.leaderBoardTV.addSubview(refreshControl)
}
func setUpOnViewWillAppear()
{
bottomScroll.contentSize.width = self.view.frame.size.width * 3
self.showNoRecordView(isShow: false)
}
func setUpOnViewWillDisappear()
{
}
func setUpOnViewDidAppear()
{
}
func updateTabBarButton()
{
DispatchQueue.main.async {
let x = CGFloat(self.presenterD.currentTimePeriod - 1) * self.bottomScroll.frame.width
UIView.animate(withDuration: TimeInterval(kFYZeroFractionThreeVar), animations: {
self.bottomScroll.setContentOffset(CGPoint(x: x, y: 0), animated: false)
self.contentView.frame.origin.x = x
self.weekBtn.alpha = 0.7
self.monthBtn.alpha = 0.7
self.allTimeBtn.alpha = 0.7
self.weekBtn.layer.borderWidth = 0
self.monthBtn.layer.borderWidth = 0
self.allTimeBtn.layer.borderWidth = 0
(self.topScrollView.viewWithTag(self.presenterD.currentTimePeriod) as! UIButton).alpha = 1.0
(self.topScrollView.viewWithTag(self.presenterD.currentTimePeriod) as! UIButton).layer.borderWidth = 1.0
}, completion:{(value: Bool) in
print("xyz\(self.contentView.frame)")
self.contentView.frame.origin.x = x
// self.bottomScroll.contentOffset.x = self.contentView.frame.origin.x
// self.contentView.frame.origin.x = self.bottomScroll.bounds.size.width * CGFloat(self.presenterD.currentTimePeriod)
// self.contentView.frame = CGRect(x: self.bottomScroll.bounds.size.width * CGFloat(self.presenterD.currentTimePeriod), y: 0, width: self.contentView.bounds.size.width, height: self.contentView.bounds.size.height)
})
}
}
/**
This will show or hide progress view on screen
- Parameter isShow: bool value to perform show/hide
*/
func showHideProgressView( _ isShow :Bool)
{
DispatchQueue.main.async {
if(isShow)
{
self.activityIndicator.startAnimating()
self.view.isUserInteractionEnabled = !isShow;
}
else
{
self.activityIndicator.stopAnimating()
self.view.isUserInteractionEnabled = !isShow;
}
}
}
func reloadList(isData : Bool)
{
DispatchQueue.main.async {
self.showNoRecordView(isShow: false)
self.leaderBoardTV.reloadData()
}
}
//MARK:- TableView Data Source
func numberOfSections(in tableView: UITableView) -> Int
{
if presenterD.currentSegment == 4
{
return 1
}
else
{
return presenterD.numberOfTeam
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if presenterD.currentSegment == 4
{
return presenterD.numberOfRowForEveryOne
}
else
{
return presenterD.numberOfRowInTeam(section : section)
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if(presenterD.currentSegment == 4)
{
let everyOneCell = tableView.dequeueReusableCell(withIdentifier: "LeaderBoardEveryOneCell")! as! LeaderBoardEveryOneCell
presenterD.configureEveryOneCell(cell: everyOneCell, row: indexPath.row)
print(self.presenterD.lBEveryOneData[0])
return everyOneCell
}
else
{
let teamCell = tableView.dequeueReusableCell(withIdentifier: "LeaderBoardTeamCell")! as! LeaderBoardTeamCell
presenterD.configureTeamCell(cell: teamCell, indexPath: indexPath)
return teamCell
}
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
if(presenterD.currentSegment == 5)
{
let view : LeaderBoardHeaderView = LeaderBoardHeaderView.instanceFromNib()
presenterD.configureHeaderView(leaderBoardHeaderView: view, section: section)
return view
}
else
{
return nil
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
if(presenterD.currentSegment == 5)
{
return 30.0
}
else
{
return 0.0
}
}
//MARK:- Other private method
fileprivate func showNoRecordView(isShow : Bool)
{
DispatchQueue.main.async {
if isShow
{
self.noRecordL.alpha = 1
self.contentView.alpha = 0
}
else
{
self.noRecordL.alpha = 0
self.contentView.alpha = 1
}
}
}
/**
Called when user refresh the leader board table
- Parameter refreshControl: sender object
*/
@objc fileprivate func refreshAction(refreshControl : UIRefreshControl)
{
DispatchQueue.main.async {
self.view.isUserInteractionEnabled = false
refreshControl.beginRefreshing()
}
presenterD.performForLeaderBoardRefresh(successHandler: { isSuccess in
DispatchQueue.main.async {
refreshControl.endRefreshing()
self.view.isUserInteractionEnabled = true
self.reloadList(isData: isSuccess)
}
}, errorHandler: {
DispatchQueue.main.async {
refreshControl.endRefreshing()
self.view.isUserInteractionEnabled = true
}
})
}
}
答案 0 :(得分:2)
这里的问题很简单。 presenterD
变量的类型为LeaderBoardPresenterP
,而不是其实现LeaderBoardPresenterImplimentation
。但是,lBEveryOneData
属性在LeaderBoardPresenterImplimentation
中定义,而不在LeaderBoardPresenterP
协议中定义。因此,从类型系统的角度来看,presenterD
没有lBEveryOneData
属性(尽管变量引用的真实对象具有此属性)。
使其可访问的一种方法是将该属性添加到协议(我猜你更喜欢):
protocol LeaderBoardPresenterP : class {
// one way to make it accessible is to declare that property in the protocol:
var lBEveryOneData: Array<LeaderBoardModel> { get set }
var currentTimePeriod : Int {get}
var currentSegment : Int { get}
var numberOfTeam : Int{ get }
var numberOfRowForEveryOne : Int{ get }
func viewDidLoad()
func viewDidAppear()
func viewWillAppear()
func tabBarBtnTap(index : Int)
func segmentBtnTap(index : Int)
func numberOfRowInTeam(section : Int)->(Int)
func configureHeaderView(leaderBoardHeaderView : LeaderBoardHeaderView, section : Int)
func configureTeamCell(cell : LeaderBoardTeamCell, indexPath : IndexPath)
func configureEveryOneCell(cell : LeaderBoardEveryOneCell, row : Int)
func performForLeaderBoardRefresh(successHandler: @escaping(Bool)->(), errorHandler : @escaping()->())
}
另一种方法是将presenterD
的类型从LeaderBoardPresenterP
类型更改为LeaderBoardPresenterImplimentation
- 但这会破坏协议的目的。