L'erreur suivante s'affiche lorsque j'utilise du code pour une extension. Je ne sais pas s'ils demandent simplement d'utiliser un autre opérateur ou de modifier les valeurs de l'expression en fonction d'une recherche Internet.
Erreur:% est indisponible: utilisez plutôt truncatingRemainder
Code d'extension:
extension CMTime {
var durationText:String {
let totalSeconds = CMTimeGetSeconds(self)
let hours:Int = Int(totalSeconds / 3600)
let minutes:Int = Int(totalSeconds % 3600 / 60)
let seconds:Int = Int(totalSeconds % 60)
if hours > 0 {
return String(format: "%i:%02i:%02i", hours, minutes, seconds)
} else {
return String(format: "%02i:%02i", minutes, seconds)
}
}
}
La ou les erreurs se produisent lors de la définition des variables minutes et secondes.
CMTimeGetSeconds()
renvoie un nombre à virgule flottante (Float64
aka Double
). Dans Swift 2, vous pouvez calculer le reste d’une division en virgule flottante comme
let rem = 2.5 % 1.1
print(rem) // 0.3
Dans Swift 3, cela se fait avec
let rem = 2.5.truncatingRemainder(dividingBy: 1.1)
print(rem) // 0.3
Appliqué à votre code:
let totalSeconds = CMTimeGetSeconds(self)
let hours = Int(totalSeconds / 3600)
let minutes = Int((totalSeconds.truncatingRemainder(dividingBy: 3600)) / 60)
let seconds = Int(totalSeconds.truncatingRemainder(dividingBy: 60))
Cependant, dans ce cas particulier, il est plus facile de convertir la durée en un entier en premier lieu:
let totalSeconds = Int(CMTimeGetSeconds(self)) // Truncate to integer
// Or:
let totalSeconds = lrint(CMTimeGetSeconds(self)) // Round to nearest integer
Ensuite, les lignes suivantes se simplifient pour
let hours = totalSeconds / 3600
let minutes = (totalSeconds % 3600) / 60
let seconds = totalSeconds % 60
L'opérateur de module %
est défini uniquement pour les types entiers. Pour les types à virgule flottante, vous devez préciser le type de comportement de division/reste IEEE 754 souhaité. Vous devez donc appeler une méthode: remainder
ou truncatingRemainder
=. (Si vous faites des calculs en virgule flottante, vous devez vraiment vous soucier de cela, et plein d'autres choses , ou vous pouvez obtenir des résultats inattendus/mauvais.)
Si vous avez réellement l'intention de faire un module entier, vous devez convertir la valeur de retour de CMTimeGetSeconds
en entier avant d'utiliser %
. (Notez que si vous le faites, vous réduirez la fraction de seconde ... en fonction de l'endroit où vous utilisez CMTime
, cela peut être important. Voulez-vous des minutes: secondes: images, par exemple?)
Selon la manière dont vous souhaitez présenter les valeurs CMTime
dans votre interface utilisateur, il peut être préférable d'extraire la valeur en secondes et de la transmettre à NSDateFormatter
ou NSDateComponentsFormatter
afin d'obtenir le support de paramètres régionaux approprié.
Cette syntaxe a en fait été suggérée sur la liste de diffusion officielle d'Apple Swift ici , mais pour une raison quelconque, ils ont opté pour une syntaxe moins élégante.
infix operator %%/*<--infix operator is required for custom infix char combos*/
/**
* Brings back simple modulo syntax (was removed in Swift 3)
* Calculates the remainder of expression1 divided by expression2
* The sign of the modulo result matches the sign of the dividend (the first number). For example, -4 % 3 and -4 % -3 both evaluate to -1
* EXAMPLE:
* print(12 %% 5) // 2
* print(4.3 %% 2.1) // 0.0999999999999996
* print(4 %% 4) // 0
* NOTE: The first print returns 2, rather than 12/5 or 2.4, because the modulo (%) operator returns only the remainder. The second trace returns 0.0999999999999996 instead of the expected 0.1 because of the limitations of floating-point accuracy in binary computing.
* NOTE: Int's can still use single %
* NOTE: there is also .remainder which supports returning negatives as oppose to truncatingRemainder (aka the old %) which returns only positive.
*/
public func %% (left:CGFloat, right:CGFloat) -> CGFloat {
return left.truncatingRemainder(dividingBy: right)
}
Cette astuce de migration simple Swift 3 fait partie d'un guide de migration plus exhaustif Swift 3 avec de nombreuses informations (35k loc/8 jours de migration) http: // eon .codes/blog/2017/01/12/Swift-3-migration /
J'ai trouvé que ce qui suit fonctionne dans Swift 3:
let minutes = Int(floor(totalSeconds / 60))
let seconds = Int(totalSeconds) % 60
où totalSeconds
est un TimeInterval
(Double
).