UIView Sembunyikan / Tampilkan dengan animasi


154

Tujuan sederhana saya adalah memudarkan fungsi persembunyian dan tampilan yang hidup.

Button.hidden = YES;

Cukup sederhana. Namun, mungkinkah membuatnya menghilang daripada hanya menghilang? Terlihat agak tidak profesional seperti itu.

Jawaban:


259

Di iOS 4 dan yang lebih baru, ada cara untuk melakukan ini hanya dengan menggunakan metode transisi UIView tanpa perlu mengimpor QuartzCore. Anda bisa mengatakan:

Tujuan C

[UIView transitionWithView:button
                  duration:0.4
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                     button.hidden = YES;
                }
                completion:NULL];

Cepat

UIView.transition(with: button, duration: 0.4, 
                  options: .transitionCrossDissolve, 
                  animations: {
                 button.hidden = false
              })

Solusi Sebelumnya

Solusi Michail akan berhasil, tetapi itu sebenarnya bukan pendekatan terbaik.

Masalah dengan alpha fading adalah kadang-kadang lapisan tampilan yang tumpang tindih yang berbeda terlihat aneh saat mereka memudar. Ada beberapa alternatif lain menggunakan Core Animation. Pertama, sertakan kerangka kerja QuartzCore di aplikasi Anda dan tambahkan #import <QuartzCore/QuartzCore.h>ke tajuk Anda. Sekarang Anda dapat melakukan salah satu dari yang berikut:

1) atur button.layer.shouldRasterize = YES;dan kemudian gunakan kode animasi alfa yang diberikan Michail dalam jawabannya. Ini akan mencegah lapisan dari campuran aneh, tetapi memiliki penalti kinerja yang sedikit, dan dapat membuat tombol terlihat buram jika tidak selaras tepat pada batas piksel.

Kalau tidak:

2) Gunakan kode berikut untuk menghidupkan fade sebagai gantinya:

CATransition *animation = [CATransition animation];
animation.type = kCATransitionFade;
animation.duration = 0.4;
[button.layer addAnimation:animation forKey:nil];

button.hidden = YES;

Yang menyenangkan tentang pendekatan ini adalah Anda dapat melakukan crossfade properti apa pun dari tombol meskipun mereka tidak dapat digerakkan (mis. Teks atau gambar tombol), cukup atur transisi dan kemudian atur properti Anda segera setelahnya.


5
@robmathers, saya hanya menguji kode Anda, di atas dua kode hanya berfungsi ketika button.hidden = TIDAK, untuk memudar dalam situasi; tidak memiliki efek animasi untuk menghilang ketika button.hidden = YES;
Jason

Tampaknya rusak di iOS 12.0
user3532505

5
Anda harus menggunakan superview dari hal yang Anda animasikan sebagai transitionWithViewparameter untuk memastikan keberhasilan memudar dan keluar.
allenh

159

Properti animasi UIView adalah:

- frame
- bounds
- center
- transform
- alpha
- backgroundColor
- contentStretch

Jelaskan dalam: Animasi

isHidden bukan salah satu dari mereka, jadi seperti yang saya lihat, cara terbaik adalah:

Swift 4:

func setView(view: UIView, hidden: Bool) {
    UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
        view.isHidden = hidden
    })
}

Sasaran C:

- (void)setView:(UIView*)view hidden:(BOOL)hidden {
    [UIView transitionWithView:view duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^(void){
        [view setHidden:hidden];
    } completion:nil];
}

8
Sebenarnya ini adalah jawaban yang sederhana dan terbaik
Irshad Mohamed

3
Meskipun ini menjiwai dengan benar, UISearchBar yang saya coba tampilkan muncul di lokasi yang salah sampai animasi selesai dan kemudian langsung melompat ke posisi yang benar. Ada ide? Saya menggunakan Storyboard dengan Interface Builder dan Constraints.
Greg Hilston

5
Kode ini tidak berfungsi ... langsung mengubah status tanpa menjiwai
Mihir Mehta

2
@evya Hanya bekerja untuk memudar ketika disembunyikan = TIDAK, tidak bekerja untuk memudar, disembunyikan = YA
Jason

Luar biasa. 10x banyak
Vyacheslav

125

Untuk menghilang:

Objektif-C

[UIView animateWithDuration:0.3 animations:^{
    button.alpha = 0;
} completion: ^(BOOL finished) {//creates a variable (BOOL) called "finished" that is set to *YES* when animation IS completed.
    button.hidden = finished;//if animation is finished ("finished" == *YES*), then hidden = "finished" ... (aka hidden = *YES*)
}];

Cepat 2

UIView.animateWithDuration(0.3, animations: {
    button.alpha = 0
}) { (finished) in
    button.hidden = finished
}

Swift 3, 4, 5

UIView.animate(withDuration: 0.3, animations: {
    button.alpha = 0
}) { (finished) in
    button.isHidden = finished
}

Untuk memudar di:

Objektif-C

button.alpha = 0;
button.hidden = NO;
[UIView animateWithDuration:0.3 animations:^{
    button.alpha = 1;
}];

Cepat 2

button.alpha = 0
button.hidden = false
UIView.animateWithDuration(0.3) {
    button.alpha = 1
}

Swift 3, 4, 5

button.alpha = 0
button.isHidden = false
UIView.animate(withDuration: 0.3) {
    button.alpha = 1
}

menggunakan fade in / out bersamaan dengan status tersembunyi memecahkan masalah saya
ACLima

Untuk beberapa alasan, menjiwai untuk disembunyikan = YA bekerja dengan baik untuk saya, tetapi menjiwai ke disembunyikan = TIDAK tidak melakukan apa-apa, jadi kombinasi dari menjiwai alpha dan pengaturan properti tersembunyi sangat membantu.
arlomedia

Saya hanya menulis demo, tetapi hanya disembunyikan = TIDAK, memudar dalam karya-karya, aneh
Jason

9

Saya menggunakan ekstensi Swift 3 kecil ini :

extension UIView {

  func fadeIn(duration: TimeInterval = 0.5,
              delay: TimeInterval = 0.0,
              completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
    UIView.animate(withDuration: duration,
                   delay: delay,
                   options: UIViewAnimationOptions.curveEaseIn,
                   animations: {
      self.alpha = 1.0
    }, completion: completion)
  }

  func fadeOut(duration: TimeInterval = 0.5,
               delay: TimeInterval = 0.0,
               completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
    UIView.animate(withDuration: duration,
                   delay: delay,
                   options: UIViewAnimationOptions.curveEaseIn,
                   animations: {
      self.alpha = 0.0
    }, completion: completion)
  }
}

7

Cepat 3

func appearView() {
     self.myView.alpha = 0
     self.myView.isHidden = false

     UIView.animate(withDuration: 0.9, animations: {
         self.myView.alpha = 1
     }, completion: {
         finished in
         self.myView.isHidden = false
     })
}

7

cepat 4.2

dengan ekstensi:

extension UIView {
func hideWithAnimation(hidden: Bool) {
        UIView.transition(with: self, duration: 0.5, options: .transitionCrossDissolve, animations: {
            self.isHidden = hidden
        })
    }
}

metode sederhana:

func setView(view: UIView, hidden: Bool) {
    UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
        view.isHidden = hidden
    })
}

Bagaimana saya bisa menambahkan penundaan untuk yang ini?
cvdogan

7

Gunakan solusi ini untuk efek fadeOut dan fadeIn yang halus

extension UIView {
    func fadeIn(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
        self.alpha = 0.0

        UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
            self.isHidden = false
            self.alpha = 1.0
        }, completion: completion)
    }

    func fadeOut(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
        self.alpha = 1.0

        UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseOut, animations: {
            self.isHidden = true
            self.alpha = 0.0
        }, completion: completion)
    }
}

penggunaannya seperti

uielement.fadeIn()
uielement.fadeOut()

Terima kasih


fadeOutbekerja di iOS 13 hanya jika saya menghapus garis yang ditetapkan self.isHidden.
Mike Taverne

6

Aku menciptakan kategori UIViewuntuk tujuan ini dan menerapkan sedikit khusus menggigit konsep yang berbeda: visibility. Perbedaan utama dari solusi saya adalah Anda dapat menelepon [view setVisible:NO animated:YES]dan segera setelah itu memeriksa [view visible]dan mendapatkan hasil yang benar. Ini cukup sederhana tetapi sangat bermanfaat.

Selain itu, diperbolehkan untuk menghindari menggunakan "logika boolean negatif" (lihat Kode Lengkap, halaman 269, Gunakan nama variabel boolean positif untuk informasi lebih lanjut).

Cepat

UIView+Visibility.swift

import UIKit


private let UIViewVisibilityShowAnimationKey = "UIViewVisibilityShowAnimationKey"
private let UIViewVisibilityHideAnimationKey = "UIViewVisibilityHideAnimationKey"


private class UIViewAnimationDelegate: NSObject {
    weak var view: UIView?

    dynamic override func animationDidStop(animation: CAAnimation, finished: Bool) {
        guard let view = self.view where finished else {
            return
        }

        view.hidden = !view.visible
        view.removeVisibilityAnimations()
    }
}


extension UIView {

    private func removeVisibilityAnimations() {
        self.layer.removeAnimationForKey(UIViewVisibilityShowAnimationKey)
        self.layer.removeAnimationForKey(UIViewVisibilityHideAnimationKey)
    }

    var visible: Bool {
        get {
            return !self.hidden && self.layer.animationForKey(UIViewVisibilityHideAnimationKey) == nil
        }

        set {
            let visible = newValue

            guard self.visible != visible else {
                return
            }

            let animated = UIView.areAnimationsEnabled()

            self.removeVisibilityAnimations()

            guard animated else {
                self.hidden = !visible
                return
            }

            self.hidden = false

            let delegate = UIViewAnimationDelegate()
            delegate.view = self

            let animation = CABasicAnimation(keyPath: "opacity")
            animation.fromValue = visible ? 0.0 : 1.0
            animation.toValue = visible ? 1.0 : 0.0
            animation.fillMode = kCAFillModeForwards
            animation.removedOnCompletion = false
            animation.delegate = delegate

            self.layer.addAnimation(animation, forKey: visible ? UIViewVisibilityShowAnimationKey : UIViewVisibilityHideAnimationKey)
        }
    }

    func setVisible(visible: Bool, animated: Bool) {
        let wereAnimationsEnabled = UIView.areAnimationsEnabled()

        if wereAnimationsEnabled != animated {
            UIView.setAnimationsEnabled(animated)
            defer { UIView.setAnimationsEnabled(!animated) }
        }

        self.visible = visible
    }

}

Objektif-C

UIView+Visibility.h

#import <UIKit/UIKit.h>

@interface UIView (Visibility)

- (BOOL)visible;
- (void)setVisible:(BOOL)visible;
- (void)setVisible:(BOOL)visible animated:(BOOL)animated;

@end

UIView+Visibility.m

#import "UIView+Visibility.h"

NSString *const UIViewVisibilityAnimationKeyShow = @"UIViewVisibilityAnimationKeyShow";
NSString *const UIViewVisibilityAnimationKeyHide = @"UIViewVisibilityAnimationKeyHide";

@implementation UIView (Visibility)

- (BOOL)visible
{
    if (self.hidden || [self.layer animationForKey:UIViewVisibilityAnimationKeyHide]) {
        return NO;
    }

    return YES;
}

- (void)setVisible:(BOOL)visible
{
    [self setVisible:visible animated:NO];
}

- (void)setVisible:(BOOL)visible animated:(BOOL)animated
{
    if (self.visible == visible) {
        return;
    }

    [self.layer removeAnimationForKey:UIViewVisibilityAnimationKeyShow];
    [self.layer removeAnimationForKey:UIViewVisibilityAnimationKeyHide];

    if (!animated) {
        self.alpha = 1.f;
        self.hidden = !visible;
        return;
    }

    self.hidden = NO;

    CGFloat fromAlpha = visible ? 0.f : 1.f;
    CGFloat toAlpha = visible ? 1.f : 0.f;
    NSString *animationKey = visible ? UIViewVisibilityAnimationKeyShow : UIViewVisibilityAnimationKeyHide;

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    animation.duration = 0.25;
    animation.fromValue = @(fromAlpha);
    animation.toValue = @(toAlpha);
    animation.delegate = self;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    [self.layer addAnimation:animation forKey:animationKey];
}

#pragma mark - CAAnimationDelegate

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished
{
    if ([[self.layer animationForKey:UIViewVisibilityAnimationKeyHide] isEqual:animation]) {
        self.hidden = YES;
    }
}

@end

@valentin shergin Versi Swift akan datang?
Juan Boero

Tentu! Saya telah menambahkan versi Swift.
Valentin Shergin

5

kode @Umair Afzal bekerja dengan baik di swift 5 setelah beberapa perubahan

 extension UIView {

func fadeIn(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
    self.alpha = 0.0

    UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
        self.isHidden = false
        self.alpha = 1.0
    }, completion: completion)
}

func fadeOut(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
    self.alpha = 1.0

    UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
        self.alpha = 0.0
    }) { (completed) in
        self.isHidden = true
        completion(true)
    }
  }
}

untuk digunakan

yourView.fadeOut()
yourView.fadeIn()

memberikan efek keras saat fadeout, menambahkan beberapa solusi yang lebih baik di sini
Dhanu K

4

Cepat 4

extension UIView {

func fadeIn(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
    self.alpha = 0.0

    UIView.animate(withDuration: duration, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations: {
        self.isHidden = false
        self.alpha = 1.0
    }, completion: completion)
}

func fadeOut(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
    self.alpha = 1.0

    UIView.animate(withDuration: duration, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations: {
        self.alpha = 0.0
    }) { (completed) in
        self.isHidden = true
        completion(true)
    }
}
}

Dan untuk menggunakannya, panggil fungsi-fungsi ini seperti:

yourView.fadeOut() // this will hide your view with animation
yourView.fadeIn() /// this will show your view with animation

Anda baru saja menyalin jawaban @ MarkMckelvie`s
Ashley Mills

Ada perbedaan, dia tidak menyembunyikan pandangan. Dan saya juga perlu menyembunyikan pandangan itu. Begitu juga dan membagikannya.
Umair Afzal

3
Mengapa tidak mengomentari jawaban yang lain alih-alih menyalinnya dan meneruskannya sebagai jawaban Anda sendiri?
Ashley Mills

2

isHidden adalah nilai langsung dan Anda tidak dapat mempengaruhi animasi di atasnya, alih-alih ini Anda dapat menggunakan Alpha untuk menyembunyikan tampilan Anda

UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
        view.alpha = 0
    })

Dan untuk menunjukkan:

UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
      view.alpha = 1
})

1

Anda dapat melakukannya dengan SANGAT mudah menggunakan perpustakaan Animatics :

//To hide button:
AlphaAnimator(0) ~> button

//to show button
AlphaAnimator(1) ~> button

1
func flipViews(fromView: UIView, toView: UIView) {

    toView.frame.origin.y = 0

    self.view.isUserInteractionEnabled = false

    UIView.transition(from: fromView, to: toView, duration: 0.5, options: .transitionFlipFromLeft, completion: { finished in            

        fromView.frame.origin.y = -900

        self.view.isUserInteractionEnabled = true

    })


}

1

Anda bisa mencoba ini.

 func showView(objView:UIView){

    objView.alpha = 0.0
    UIView.animate(withDuration: 0.5, animations: {
        objView.alpha = 0.0
    }, completion: { (completeFadein: Bool) -> Void in
        objView.alpha = 1.0
        let transition = CATransition()
        transition.duration = 0.5
        transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition.type = kCATransitionFade
        objView.layer.add(transition, forKey: nil)
    })
}

func HideView(objView:UIView){

    UIView.animate(withDuration: 0.5, animations: {
        objView.alpha = 1.0
    }, completion: { (completeFadein: Bool) -> Void in
        objView.alpha = 0.0
        let transition = CATransition()
        transition.duration = 0.5
        transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition.type = kCATransitionFade
        objView.layer.add(transition, forKey: nil)
    })
}

Dan berikan nama tampilan Anda

        showView(objView: self.viewSaveCard)
        HideView(objView: self.viewSaveCard)

1

Jika tampilan Anda disetel ke tersembunyi secara default atau Anda mengubah status Tersembunyi yang menurut saya harus Anda lakukan dalam banyak kasus, maka tidak ada pendekatan di halaman ini yang akan memberi Anda animasi FadeIn / FadeOut, itu hanya akan menganimasikan salah satu dari status ini, alasannya adalah Anda mengatur status Tersembunyi ke false sebelum memanggil metode UIView.animate yang akan menyebabkan visibilitas mendadak dan jika Anda hanya menghidupkan alpha maka ruang objek masih ada tetapi tidak terlihat yang akan mengakibatkan beberapa masalah UI.

Jadi pendekatan terbaik adalah memeriksa dulu jika tampilan disembunyikan lalu atur alpha menjadi 0,0, seperti ini saat Anda mengatur status Tersembunyi menjadi false Anda tidak akan melihat visibilitas mendadak.

func hideViewWithFade(_ view: UIView) {
    if view.isHidden {
        view.alpha = 0.0
    }

    view.isHidden = false

    UIView.animate(withDuration: 0.3, delay: 0.0, options: .transitionCrossDissolve, animations: {
        view.alpha = view.alpha == 1.0 ? 0.0 : 1.0
    }, completion: { _ in
        view.isHidden = !Bool(truncating: view.alpha as NSNumber)
    })
}

Ini menyelesaikan masalah yang orang lain tanyakan tentang di mana fadein tidak berfungsi. Pendekatan cerdas.
BooTooMany

1

Fungsi UIView.transition (with :) bagus dan rapi.

Banyak yang mempostingnya tetapi tidak ada yang menyadari bahwa ada kesalahan yang akan muncul hanya ketika Anda menjalankannya.

Anda dapat mentransisikan properti tersembunyi ke true dengan sempurna, sedangkan saat Anda mencoba mengalihkannya ke false, tampilan akan menghilang secara tiba-tiba tanpa animasi.

Itu karena api ini hanya berfungsi dalam tampilan, yang berarti ketika Anda mentransisikan tampilan untuk ditampilkan, sebenarnya itu langsung ditampilkan, hanya kontennya yang keluar secara bertahap.

Ketika Anda mencoba untuk menyembunyikan tampilan ini, itu sendiri bersembunyi segera, membuat animasi menjadi isinya tidak berarti.

Untuk mengatasi ini, saat menyembunyikan tampilan, target transisi haruslah tampilan induknya, bukan tampilan yang ingin Anda sembunyikan.

func transitionView(_ view: UIView?, show: Bool, completion: BoolFunc? = nil) {
    guard let view = view, view.isHidden == show, let parent = view.superview else { return }

    let target: UIView = show ? view : parent
    UIView.transition(with: target, duration: 0.4, options: [.transitionCrossDissolve], animations: {
        view.isHidden = !show
    }, completion: completion)
}

0

Solusi saya untuk Swift 3 . Jadi, saya membuat fungsi, yang menyembunyikan / menyembunyikan tampilan dalam urutan yang benar (ketika menyembunyikan - set alpha ke 0 dan kemudian IsHidden ke true; unhiding - pertama mengungkapkan view dan kemudian mengatur alpha ke 1):

func hide(_ hide: Bool) {
    let animations = hide ? { self.alpha = 0 } :
                            { self.isHidden = false }
    let completion: (Bool) -> Void = hide ? { _ in self.isHidden = true } :
                                            { _ in UIView.animate(withDuration: duration, animations: { self.alpha = 1 }) }
    UIView.animate(withDuration: duration, animations: animations, completion: completion)
}

Mengapa di completionblok ada animasi lain ketika hideitu salah?
Giorgio

0

Swift 4 Transition

    UIView.transition(with: view, duration: 3, options: .transitionCurlDown,
                      animations: {
                        // Animations
                        view.isHidden = hidden
    },
                      completion: { finished in
                        // Compeleted
    })

Jika Anda menggunakan pendekatan untuk versi cepat swift Anda akan mendapatkan kesalahan:

Cannot convert value of type '(_) -> ()' to expected argument type '(() -> Void)?'

Referensi yang berguna .


apakah ini berfungsi dengan pembayaran otomatis? kode serupa tidak menjiwai. yang isHiddennilai diberikan langsung (yaitu, langsung bersembunyi / menampilkan tampilan).
Crashalot

0

Kode ini memberikan animasi seperti mendorong viewController di pengontrol navigasi ...

CATransition *animation = [CATransition animation];
 animation.type = kCATransitionPush;
 animation.subtype = kCATransitionFromRight;
 animation.duration = 0.3;
 [_viewAccountName.layer addAnimation:animation forKey:nil];

 _viewAccountName.hidden = true;

Digunakan ini untuk animasi pop ...

 CATransition *animation = [CATransition animation];
 animation.type = kCATransitionPush;
 animation.subtype = kCATransitionFromLeft;
 animation.duration = 0.3;
 [_viewAccountName.layer addAnimation:animation forKey:nil];

 _viewAccountName.hidden = false;

0

Mencoba beberapa jawaban yang keluar, beberapa hanya berfungsi untuk satu situasi, beberapa dari mereka perlu menambahkan dua fungsi.

Pilihan 1

Tidak ada hubungannya dengan view.isHidden.

extension UIView {
    func animate(fadeIn: Bool, withDuration: TimeInterval = 1.0) {
        UIView.animate(withDuration: withDuration, delay: 0.0, options: .curveEaseInOut, animations: {
            self.alpha = fadeIn ? 1.0 : 0.0
        })
    }
}

Kemudian lulus isFadeIn( trueatau false)

view.animate(fadeIn: isFadeIn) 

pilihan 2

Jangan melewati parameter apa pun. Itu memudar masuk atau keluar menurut isUserInteractionEnabled. Ini juga cocok dengan situasi menghidupkan dan bolak-balik dengan sangat baik.

func animateFadeInOut(withDuration: TimeInterval = 1.0) {
    self.isUserInteractionEnabled = !self.isUserInteractionEnabled
    UIView.animate(withDuration: withDuration, delay: 0.0, options: .curveEaseInOut, animations: {
        self.alpha = self.isUserInteractionEnabled ? 1.0 : 0.0
    })
}

Lalu kamu menelepon

yourView.animateFadeInOut()

Mengapa self.isUserInteractionEnabled?

Mencoba untuk mengganti self.isUserInteractionEnableddengan self.isHidden, tidak beruntung sama sekali.

Itu dia. Biaya saya kapan saja, semoga membantu seseorang.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.