【发布时间】:2020-10-15 20:10:28
【问题描述】:
我尝试在按下 navigationItem 的按钮时触发活动指示器的动画。但我发现活动指示器没有旋转。我尝试将scanerIndicator.startAnimating() 放入主线程,但没有帮助。
代码是采集路由器打开的端口,我想在按下navigationItem按钮时开始旋转,在返回openPorts时停止旋转。感谢任何关于哪里出错的线索/提示?
override func viewDidLoad() {
super.viewDidLoad()
...
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Start", style: .plain, target: self, action: #selector(startScan))
...
}
@objc func startScan() {
scanerIndicator.startAnimating()
if let address = serverAddress.text, !address.isEmpty {
if let start = Int(startPort.text!) {
if let stop = Int(stopPort.text!) {
if start < stop {
openPorts = netUtility.scanPorts(address: address, start: start, stop: stop)
print("Open Open: \(openPorts)")
if !openPorts.isEmpty {
scanerIndicator.stopAnimating()
table.reloadData()
} else {
showErrorMessage(errorTitle: "Not at all", errorMessage: "No open ports were found")
}
} else {
showErrorMessage(errorTitle: "Range error", errorMessage: "Start port should be smaller than stop port")
}
} else {
showErrorMessage(errorTitle: "Empty fields", errorMessage: "Please fill all the necessary data")
}
} else {
showErrorMessage(errorTitle: "Empty fields", errorMessage: "Please fill all the necessary data")
}
} else {
showErrorMessage(errorTitle: "Empty fields", errorMessage: "Please fill all the necessary data")
}
}
收集端口的代码:
// MARK: - Port Scaner
// Get number of threads for scan ports
func getSegmentsQueues(min: Int, max: Int, maxPerSegment: Int) -> [[Int]] {
var start: Int = min
var portSegments = [[Int]]()
while start <= max {
var _portSegment = [Int]()
for _ in 1...maxPerSegment {
if start <= max {
_portSegment.append(start)
}
start += 1
}
portSegments.append(_portSegment)
}
return portSegments
}
// Crate queques for scan ports by segments
func QueueDispatchPort(address: String, minPort: Int, maxPort: Int, segmentsQueues: (Int, Int, Int) -> [[Int]]) -> [Int] {
var openPorts : [Int] = []
let segmentPorts = segmentsQueues(minPort, maxPort, 1);
let group = DispatchGroup()
for segment in segmentPorts {
group.enter()
DispatchQueue.global().async {
for port in segment {
let client = TCPClient(address: address, port: Int32(port))
switch client.connect(timeout: 2) {
case .success:
openPorts.append(port)
case .failure(_):
print("port \(port) closed")
}
client.close()
}
group.leave()
}
}
group.wait()
return openPorts
}
// Scans ports from an address and a range given by the user
func scanPorts(address : String, start : Int, stop : Int) -> [Int] {
let openPorts = QueueDispatchPort(
address: address, minPort: start, maxPort: stop, segmentsQueues:
getSegmentsQueues(min:max:maxPerSegment:))
return openPorts
}
代码更新,我将这段代码(扫描端口)放在主线程上,这次删除了stopAnimating()。在长时间运行代码返回(DispatchQueue.main 中的内容)后,activityIndicator 会被动画化。还是不行……
@objc func startScan() {
scanerIndicator.startAnimating()
DispatchQueue.main.async { [self] in
if let address = serverAddress.text, !address.isEmpty {
if let start = Int(startPort.text!) {
if let stop = Int(stopPort.text!) {
if start < stop {
openPorts = netUtility.scanPorts(address: address, start: start, stop: stop)
print("Open Open: \(openPorts)")
if !openPorts.isEmpty {
table.reloadData()
} else {
showErrorMessage(errorTitle: "Not at all", errorMessage: "No open ports were found")
}
} else {
showErrorMessage(errorTitle: "Range error", errorMessage: "Start port should be smaller than stop port")
}
} else {
showErrorMessage(errorTitle: "Empty fields", errorMessage: "Please fill all the necessary data")
}
} else {
showErrorMessage(errorTitle: "Empty fields", errorMessage: "Please fill all the necessary data")
}
} else {
showErrorMessage(errorTitle: "Empty fields", errorMessage: "Please fill all the necessary data")
}
}
}
【问题讨论】:
标签: swift uiactivityindicatorview