বর্তমানভিউ কনট্রোলার: অ্যানিমেটেড: ব্যবহারকারীদের আবার আলতো চাপ না দেওয়া পর্যন্ত হ্যাঁ দৃশ্যটি উপস্থিত হবে না


93

আমি কিছু অদ্ভুত আচরণ করছি presentViewController:animated:completion। আমি যা বানাচ্ছি তা মূলত অনুমান করার একটি খেলা।

আমার একটি UIViewController(ফ্রিকোয়েন্সিভিউ কনট্রোলার) রয়েছে যার একটি UITableView(ফ্রিকোয়েন্সিট্যাবলভিউ) রয়েছে। ব্যবহারকারী যখন সঠিক উত্তর সম্বলিত প্রশ্নেবলটে ভিউতে সারিটিতে টোকা দেয়, তখন একটি ভিউ (बरोबरভিউ কনট্রোলার) তাত্ক্ষণিক হওয়া উচিত এবং এর ভিউটি একটি মডেল ভিউ হিসাবে পর্দার নীচে থেকে স্লাইড হওয়া উচিত। এটি ব্যবহারকারীদের তাদের সঠিক উত্তর রয়েছে এবং তার পরবর্তী ফ্রিকোয়েন্সি ভিউকন্ট্রোলারটিকে পুনরায় সেট করে পরবর্তী প্রশ্নের জন্য প্রস্তুত রয়েছে ts পরের প্রশ্নটি প্রকাশের জন্য বাটন টিপে সঠিকভিউ নিয়ন্ত্রণকারীকে বরখাস্ত করা হবে।

এই সব সঠিকভাবে প্রত্যেক সময় কাজ করে, এবং correctViewController দৃষ্টিভঙ্গি যতদিন অবিলম্বে প্রদর্শিত presentViewController:animated:completionহয়েছে animated:NO

যদি আমি সেট করে animated:YESরাখি, সঠিকভিউকন্ট্রোলারটি আরম্ভ করা হয়ে কল করে viewDidLoad। যাইহোক viewWillAppear, viewDidAppearএবং সম্পূর্ণ হওয়া ব্লকটি কল করা presentViewController:animated:completionহয় না। আমি দ্বিতীয় ট্যাপ না করা পর্যন্ত অ্যাপ্লিকেশনটি এখনও সেখানে বসে ফ্রিকোয়েন্সিভিউকন্ট্রোলার দেখায়। এখন, ভিউউইল অ্যাপয়ার, ভিউডিডঅ্যাপার এবং সমাপ্তি ব্লককে ডাকা হবে।

আমি আরও কিছুটা তদন্ত করেছি এবং এটি কেবলমাত্র অন্য একটি ট্যাপ নয় যা এটি চালিয়ে যাওয়ার কারণ হবে। দেখে মনে হচ্ছে যদি আমি আমার আইফোনকে টিল্ট করে রাখি বা কাঁপিয়েছি এটি এর ফলেও ভিউলল্ড ইত্যাদির কারণ হতে পারে can এটির মতো এটির উন্নতি হওয়ার আগে এটি অন্য কোনও বিট ইউজার ইনপুটটির জন্য অপেক্ষা করছে। এটি একটি আসল আইফোনে এবং সিমুলেটারে ঘটেছিল, যা আমি সিমুলেটরে শেক কমান্ড প্রেরণ করে প্রমাণ করেছি।

এই সম্পর্কে কী করা উচিত তা আমি সত্যিই ক্ষতির মুখোমুখি হয়েছি ... যে কেউ যে কোনও সহায়তা দিতে পারে তার আমি সত্যই প্রশংসা করব।

ধন্যবাদ

আমার কোড এখানে। এটা বেশ সহজ ...

এটি প্রশ্নভিউ কনট্রোলারের কোড যা প্রশ্নাবলী টেবিউয়ের প্রতিনিধি হিসাবে কাজ করে

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    if (indexPath.row != [self.frequencyModel currentFrequencyIndex])
    {
        // If guess was wrong, then mark the selection as incorrect
        NSLog(@"Incorrect Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);
        UITableViewCell *cell = [self.frequencyTableView cellForRowAtIndexPath:indexPath];
        [cell setBackgroundColor:[UIColor colorWithRed:240/255.0f green:110/255.0f blue:103/255.0f alpha:1.0f]];            
    }
    else
    {
        // If guess was correct, show correct view
        NSLog(@"Correct Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);
        self.correctViewController = [[HFBCorrectViewController alloc] init];
        self.correctViewController.delegate = self;
        [self presentViewController:self.correctViewController animated:YES completion:^(void){
            NSLog(@"Completed Presenting correctViewController");
            [self setUpViewForNextQuestion];
        }];
    }
}

এটি নির্ভুল ভিউকন্ট্রোলারের পুরো

@implementation HFBCorrectViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        // Custom initialization
        NSLog(@"[HFBCorrectViewController initWithNibName:bundle:]");
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    NSLog(@"[HFBCorrectViewController viewDidLoad]");
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    NSLog(@"[HFBCorrectViewController viewDidAppear]");
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)close:(id)sender
{
    NSLog(@"[HFBCorrectViewController close:sender:]");
    [self.delegate didDismissCorrectViewController];
}


@end

সম্পাদনা করুন:

আমি এই প্রশ্নটি আগে পেয়েছি: ইউআইটিএবলভিউ এবং বর্তমানভিউ কনট্রোলার প্রদর্শন করতে 2 টি ক্লিক নেয়

এবং আমি যদি আমার didSelectRowকোডটি এতে পরিবর্তন করি তবে এটি অ্যানিমেশন সহ খুব সময় কাজ করে ... তবে এটি অগোছালো এবং কেন এটি প্রথম স্থানে কাজ করে না তা বোঝায় না। সুতরাং আমি এটিকে উত্তর হিসাবে গণনা করি না ...

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    if (indexPath.row != [self.frequencyModel currentFrequencyIndex])
    {
        // If guess was wrong, then mark the selection as incorrect
        NSLog(@"Incorrect Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);
        UITableViewCell *cell = [self.frequencyTableView cellForRowAtIndexPath:indexPath];
        [cell setBackgroundColor:[UIColor colorWithRed:240/255.0f green:110/255.0f blue:103/255.0f alpha:1.0f]];
        // [cell setAccessoryType:(UITableViewCellAccessoryType)]

    }
    else
    {
        // If guess was correct, show correct view
        NSLog(@"Correct Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);

        ////////////////////////////
        // BELOW HERE ARE THE CHANGES
        [self performSelector:@selector(showCorrectViewController:) withObject:nil afterDelay:0];
    }
}

-(void)showCorrectViewController:(id)sender
{
    self.correctViewController = [[HFBCorrectViewController alloc] init];
    self.correctViewController.delegate = self;
    self.correctViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    [self presentViewController:self.correctViewController animated:YES completion:^(void){
        NSLog(@"Completed Presenting correctViewController");
        [self setUpViewForNextQuestion];
    }];
}

4
আমি একই সমস্যা আছে। আমি এনএসএলগগুলির সাথে চেক করেছিলাম যে এমন কোনও পদ্ধতিতে কল করি না যা কার্যকর করতে দীর্ঘ সময় নেয়। এটি প্রদর্শিত হয় যে এটি কেবলমাত্র অ্যানিমেশন যা presentViewController:ট্রিগার করার কথা বলে বড় দেরিতে শুরু হয়। এটি আইওএস 7-তে একটি বাগ বলে মনে হচ্ছে এবং এটি অ্যাপল দেব ফোরামেও আলোচিত।
থিও

আমি একই সমস্যা আছে। কোনও iOS7 বাগের মতো মনে হচ্ছে - iOS6 এ ঘটে না। এছাড়াও, আমার ক্ষেত্রে উপস্থাপনার ভিউ কন্ট্রোলারটি খোলার পরে এটি প্রথমবার ঘটে। @ থিও, আপনি অ্যাপল দেব ফোরামে কোনও লিঙ্ক সরবরাহ করতে পারেন?
এএক্স

উত্তর:


158

আমি আজ একই সমস্যার মুখোমুখি হয়েছি। আমি বিষয়টি খনন করেছি এবং মনে হচ্ছে এটি মূল চালনার ঘুমের সাথে সম্পর্কিত।

প্রকৃতপক্ষে এটি একটি খুব সূক্ষ্ম বাগ, কারণ আপনার কোডটিতে যদি আপনার সামান্যতম প্রতিক্রিয়া অ্যানিমেশন, টাইমারস ইত্যাদি থাকে তবে এই সমস্যাটি স্থান পাবে না কারণ এই উত্সগুলির দ্বারা রানলুপটি জীবন্ত রাখা হবে। আমি ব্যবহার করে ইস্যু পেয়েছি UITableViewCellযা তার ছিল selectionStyleসেট UITableViewCellSelectionStyleNone, যাতে কোনও নির্বাচন নেই অ্যানিমেশন সারি নির্বাচন হ্যান্ডলার দৌড়ে পালিয়ে যান runloop আলোড়ন সৃষ্টি।

এটি ঠিক করার জন্য (যতক্ষণ না অ্যাপল কিছু না করে) আপনি বেশ কয়েকটি মাধ্যমে মূল রানলুপটি ট্রিগার করতে পারেন:

সর্বনিম্ন হস্তক্ষেপমূলক কলটি কল করা CFRunLoopWakeUp:

[self presentViewController:vc animated:YES completion:nil];
CFRunLoopWakeUp(CFRunLoopGetCurrent());

অথবা আপনি একটি খালি ব্লকটি মূল কাতারে সজ্জিত করতে পারেন:

[self presentViewController:vc animated:YES completion:nil];
dispatch_async(dispatch_get_main_queue(), ^{});

এটি মজাদার, তবে আপনি যদি ডিভাইসটি নাড়িয়ে দেন তবে এটি মূল লুপটিকেও ট্রিগার করবে (এটি গতির ইভেন্টগুলি প্রক্রিয়া করতে হবে)। ট্যাপের সাথে একই জিনিস, তবে এটি মূল প্রশ্নের অন্তর্ভুক্ত রয়েছে :) এছাড়াও, যদি সিস্টেমটি স্থিতি বার আপডেট করে (যেমন ঘড়ির আপডেট, ওয়াইফাই সংকেতের শক্তি পরিবর্তন ইত্যাদি) যা প্রধান লুপটি জাগ্রত করবে এবং দৃশ্যটি উপস্থাপন করবে নিয়ামক।

আগ্রহী যে কারও জন্য আমি রোললুপ হাইপোথিসিসটি যাচাই করতে ইস্যুটির একটি সর্বনিম্ন বিক্ষোভ প্রকল্প লিখেছি: https://github.com/tzahola/premitted-bug

আমি অ্যাপলকে বাগটিও জানিয়েছি।


ধন্যবাদ ট্যামস এটি দুর্দান্ত তথ্য। এটি ব্যাখ্যা করে যে আমাকে কখনও কখনও রান লুপটি বন্ধ করার জন্য ট্যাপ করার দরকার পড়েছিল, বা কখনও কখনও কেবল অপেক্ষা করতে হয় এবং এটি কার্যকর হবে। আমি এটিকে সমাধান হিসাবে চিহ্নিত করেছি কারণ এটি মনে হচ্ছে না যে বাগটি স্থির না হওয়া পর্যন্ত আমরা কিছু করতে পারি।
হাফ

অ্যাপল একটি দুর্দান্ত গর্ত খনন করেছে, আমি এতে ফোঁটা ফেলেছি এবং খারাপভাবে অনুভব করছি।
ওপেনথ্রেড

7
ওএমজি, এতো হাসিখুশি! বিটিডাব্লু, এই বাগটি এখনও বিদ্যমান।
igrrik

4
আমার ঠিক একই সমস্যাটি সত্যই বিরক্তিকর ছিল, ধন্যবাদ এই এটি ঠিক করেছে।
চিহ্নিত করুন

4
নিশ্চিত হয়েছি যে এই সমস্যাটি এখনও আইওএস 13 এ ঘটে
এরিক হোরেসেক

69

এটি দেখুন: https://devforums.apple.com/thread/201431 আপনি যদি এটি সব পড়তে না চান - কিছু লোকের (আমাকে সহ) সমাধানের মূল সমাধানটি presentViewControllerমূল থ্রেডে করা ছিল:

সুইফট 4.2:

DispatchQueue.main.async { 
    self.present(myVC, animated: true, completion: nil)
}

উদ্দেশ্য গ:

dispatch_async(dispatch_get_main_queue(), ^{
    [self presentViewController:myVC animated:YES completion:nil];
});

সম্ভবত iOS7 এর মধ্যে থ্রেডগুলিকে গণ্ডগোল করছে didSelectRowAtIndexPath


বাহ - এটি আমার জন্য কাজ করেছে। আমিও বিলম্ব দেখছিলাম। কেন এটি প্রয়োজনীয় হবে তা আমি বুঝতে পারি না। এই পোস্ট করার জন্য ধন্যবাদ।
drudru

4
এই সমস্যাটি সম্পর্কে অ্যাপলের সাথে একটি রাডার ফাইল করা হয়েছে: rdar: // 19563577 openradar.appspot.com/19563577
mluisbrown

4
আমি আইওএস 8 এ থাকি এবং এটি আমার পক্ষে এটি ঠিক করে না - এটি সর্বদা মূল থ্রেডে থাকার প্রতিবেদন করে তবে আমি এখনও বর্ণিত সমস্যাটি দেখতে পাচ্ছি।
রবার্ট

7

নিম্নলিখিত কোড ব্যবহার করে আমি এটি সুইফট ৩.০ এ বাইপাস করেছি:

DispatchQueue.main.async { 
    self.present(UIViewController(), animated: true, completion: nil)
}

4
এটি সমস্যা সমাধান। আমার একই সমস্যা ছিল কারণ আমি presentক্লোজার কলব্যাকে কল করছি ।
জেরেমি পিডনোয়েল

2

[viewController view]উপস্থাপনা করা ভিউ কন্ট্রোলারকে কল করা আমার পক্ষে কৌশলটি করেছে।


এটি আইওএস ৮ এ আমার জন্য কাজ করেছে I
রবার্ট

0

আমি কি জানতে আগ্রহী হতে হবে [self setUpViewForNextQuestion];

আপনি [self.correctViewController.view setNeedsDisplay];নিজের সমাপ্তি ব্লকটি শেষে কল করার চেষ্টা করতে পারেন presentViewController


এই মুহুর্তে সেটআপ ভিউফরফরেক্সটকিউশন কেবল টেবিল ভিউতে পুনরায়লোডডাটা কল করে (কোনও ভুল অনুমানের দ্বারা যদি কোনও লাল সেট করা থাকে তবে ব্যাকগ্রাউন্ডের রঙগুলি সাদাতে ফিরে পরিবর্তন করতে)। কিন্তু সেখানে কোনও পরিবর্তন কি কোনও পার্থক্য আনবে? সমস্যাটি হ'ল সঠিক ভিউকন্ট্রোলারটি আবার ব্যবহারের ট্যাপ না হওয়া পর্যন্ত উপস্থিত হয় না, সুতরাং দ্বিতীয় ধাপের পরে এই সমাপ্তি ব্লকটি কল করা হবে না।
অর্ধ

আমি আপনার পরামর্শ চেষ্টা করেছিলাম, কিন্তু এটি কোনও পার্থক্য করেনি। যেমনটি আমি বলছি, দৃশ্যটি প্রদর্শিত হচ্ছে না, সুতরাং দ্বিতীয় ট্যাপের পরে বা কাঁপানোর ইশারার অবধি সমাপ্তি ব্লক ডাকা হবে না।
অর্ধনমিত

হুঁ। প্রারম্ভিকদের জন্য, আমি ব্রেকপয়েন্টগুলি ব্যবহার করব তা নিশ্চিত করার জন্য যে 2 য় ট্যাপ না হওয়া পর্যন্ত আপনার উপস্থাপনা কোডটি কল করা হয়নি। (বনাম প্রথম ট্যাপে কল করা, তবে কিছুক্ষণ পরে অনস্ক্রিনে আঁকা হচ্ছে না)। যদি পরবর্তীটি সত্য হয় তবে আপনার উপস্থাপনাটি মূল থ্রেডে ঘটতে বাধ্য করুন। আপনি যখন "পারফরমেশনসিলিটার উইথড্লে: 0" ব্যবহার করেন যা অ্যাপ্লিকেশনটিকে মৃত্যুদন্ড কার্যকর করার আগে রান লুপের পরবর্তী পুনরাবৃত্ত হওয়া পর্যন্ত অপেক্ষা করতে বাধ্য করে। এটি থ্রেডিং-সম্পর্কিত হতে পারে।
নিক

ধন্যবাদ, নিক। ব্রেকপয়েন্টগুলি ব্যবহার করে আমি কীভাবে চেক করব? এই মুহুর্তে আমি এনএসএলগকে প্রতিটি পদ্ধতি কখন ডাকা হচ্ছে তা যাচাই করার জন্য ব্যবহার করছি। ট্যাপ 1: এই আমি এখন আছে Correct Guess: 1 kHz 18:04:57.173 Frequency[641:60b] [HFBCorrectViewController initWithNibName:bundle:] 18:04:57.177 Frequency[641:60b] [HFBCorrectViewController viewDidLoad] আলতো চাপুন 2: এখন কিছুই পর্যন্ত ঘটে18:05:00.515 Frequency[641:60b] [HFBCorrectViewController viewDidAppear] 18:05:00.516 Frequency[641:60b] Completed Presenting correctViewController 18:05:00.517 Frequency[641:60b] [HFBFrequencyViewController setUpViewForNextQuestion]
HalfNormalled

দুঃখিত, আরও স্পষ্ট করা উচিত ছিল। আমি বুঝতে পারি কীভাবে ব্রেকপয়েন্টগুলি ব্যবহার করতে হয়। আমি এনএসলগের মতো একই গল্প পেয়েছি। আমি ভিজিডলিড এবং ব্রেকটিপয়েন্টগুলিকে সঠিক ভিউকন্ট্রোলারের মধ্যে রেখেছি। এটি ভিডিডলিডে ব্রেক হয়ে যায়, তারপরে যখন আমি চালিয়ে যাব, এটি বসে এবং অন্য ট্যাপের জন্য অপেক্ষা করে, তারপরে ভিউডিডঅ্যাপারে ব্রেক হয়। কখনও কখনও মনে হয় এটির জন্য কোনও ট্যাপের দরকার নেই এবং এটি সময়ভিত্তিক, যখন আমি কী কী ডাকছে তা দেখার জন্য পদক্ষেপ নেওয়ার সময়, ভিডিডলয়েড কল করার পক্ষে এটি চার্জ হয়ে যায়।
হাফ সাধারণভাবে

0

আমি ইউআইভিউউকন্ট্রোলারের জন্য পদ্ধতিটি সুইজল করে এক্সটেনশন (বিভাগ) লিখেছি যা সমস্যার সমাধান করে। বাস্তবায়ন নির্দেশ (জন্য এ এক্স এবং NSHipster ধন্যবাদ দ্রুতগতি / Objective-C )।

সুইফট

extension UIViewController {

 override public class func initialize() {
    struct DispatchToken {
      static var token: dispatch_once_t = 0
    }
    if self != UIViewController.self {
      return
    }
    dispatch_once(&DispatchToken.token) {
      let originalSelector = Selector("presentViewController:animated:completion:")
      let swizzledSelector = Selector("wrappedPresentViewController:animated:completion:")

      let originalMethod = class_getInstanceMethod(self, originalSelector)
      let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)

      let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

      if didAddMethod {
        class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
      }
      else {
        method_exchangeImplementations(originalMethod, swizzledMethod)
      }
    }
  }

  func wrappedPresentViewController(viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?) {
    dispatch_async(dispatch_get_main_queue()) {
      self.wrappedPresentViewController(viewControllerToPresent, animated: flag, completion: completion)
    }
  }
}  

উদ্দেশ্য গ

#import <objc/runtime.h>

@implementation UIViewController (Swizzling)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];

        SEL originalSelector = @selector(presentViewController:animated:completion:);
        SEL swizzledSelector = @selector(wrappedPresentViewController:animated:completion:);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        BOOL didAddMethod =
            class_addMethod(class,
                originalSelector,
                method_getImplementation(swizzledMethod),
                method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) {
            class_replaceMethod(class,
                swizzledSelector,
                method_getImplementation(originalMethod),
                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

- (void)wrappedPresentViewController:(UIViewController *)viewControllerToPresent 
                             animated:(BOOL)flag 
                           completion:(void (^ __nullable)(void))completion {
    dispatch_async(dispatch_get_main_queue(),^{
        [self wrappedPresentViewController:viewControllerToPresent
                                  animated:flag 
                                completion:completion];
    });

}

@end

0

আপনার স্টোরবোর্ডের ঘরে নির্বাচন = কিছুই নেই কিনা তা পরীক্ষা করুন

যদি তা হয় তবে এটি নীল বা ধূসরতে পরিবর্তন করুন এবং এটি কাজ করা উচিত


0

এক্সকোড ভেসিয়ন: 9.4.1, সুইফট 4.1

আমার ক্ষেত্রে এটি ঘটে, যখন আমি সেলটি ট্যাপ করি এবং অন্য দৃশ্যের জন্য চলে যাই। আমি গভীরতর মধ্যে ডিবাগ করি এবং মনে হয় যে viewDidAppearনিম্নলিখিত কোড রয়েছে বলে ভিতরে ভিতরে ঘটে

if let indexPath = tableView.indexPathForSelectedRow {
   tableView.deselectRow(at: indexPath, animated: true)
}

তারপরে আমি কোড বিভাগের উপরের অংশ জুড়েছি prepare(for segue: UIStoryboardSegue, sender: Any?)এবং নিখুঁতভাবে কাজ করি।

আমার অভিজ্ঞতার মধ্যেই আমার সমাধানটি হ'ল, যদি আমরা টেবিলভিউয়ের জন্য আবার কোনও নতুন পরিবর্তন (যেমন টেবিল পুনরায় লোড, নির্বাচিত সেল ইত্যাদি নির্বাচন না করা) করতে আশা করি, তবে আবার দ্বিতীয় দর্শন থেকে ফিরে আসার পরে প্রতিনিধি ব্যবহার করুন viewDidAppearএবং উপরের tableView.deselectRowকোডটি ব্যবহার করুন দ্বিতীয় দেখার নিয়ামক সরানোর আগে বিভাগ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.