Я создаю генератор мемов и пытаюсь скрыть панель инструментов после завершения действия. Я не уверен, почему панель инструментов всегда видна.

func generateMemedImage() -> UIImage {
        navigationController?.setToolbarHidden(false, animated: false)

        // Render view to an image
        UIGraphicsBeginImageContext(self.view.frame.size)
        view.drawHierarchy(in: self.view.frame, afterScreenUpdates: true)
        let memedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        navigationController?.setToolbarHidden(true, animated: false)
        return memedImage
    }

Эта функция вызывается следующей функцией:

func save() {
        let memedImage = generateMemedImage()
        let meme = Meme(topText: topTextField.text!, bottomText: bottomTextField.text!, originalImage: imagePickerView.image!, memedImage: memedImage)
        // Add it to the memes array in the Application Delegate
        let object = UIApplication.shared.delegate
        let appDelegate = object as! AppDelegate
        appDelegate.memes.append(meme)
        print(appDelegate.memes.count)
    }

Что затем вызывается следующим IBAction:

@IBAction func shareMeme(_ sender: Any) {
        let memedImage = generateMemedImage()
        let activityVC = UIActivityViewController(activityItems: [memedImage], applicationActivities: nil)

        activityVC.completionWithItemsHandler = {
            activity, completed, items, error in
            if completed {
                self.save()
                self.dismiss(animated: true, completion: nil)
            }
        }
        present(activityVC, animated: true, completion: nil)
    }

Я безуспешно пытался перевернуть состояния Bool в дальнейшем. Где я ошибаюсь? Здесь также есть ссылка на репо.

1
Andrew Tuzson 3 Янв 2018 в 14:17

2 ответа

Лучший ответ

Вы предполагаете, что взаимодействуете с панелью инструментов по умолчанию, вложенной в NavigationController (navigationController?.setToolbarHidden), но на самом деле вы определили пользовательский UIToolBar внутри своего Storyboard/ViewController:

enter image description here

Итак, чтобы иметь возможность переключать видимость вашего пользовательского UIToolBar, вы должны сначала подключить розетку, выполнив следующие действия:

@IBOutlet weak var toolbar: UIToolbar!

А затем, когда вы захотите это скрыть:

UIView.animate(withDuration: 0.25, animations: { self.toolbar.alpha = 0 })

Или покажите это:

UIView.animate(withDuration: 0.25, animations: { self.toolbar.alpha = 1 })
1
Andrea Mugnaini 3 Янв 2018 в 11:45

Похоже, что activityVC.completionWithItemsHandler вызывается асинхронно из потока, отличного от основного. Любое обновление пользовательского интерфейса всегда должно вызываться из основного потока, иначе это обычно приводит к странному поведению.

В вашем случае вы можете попробовать вызвать save() из основного потока, поскольку это метод, вызывающий generateMemedImage(). Это должно выглядеть примерно так:

...

if completed {
  DispatchQueue.main.async {
    self.save()
    self.dismiss(animated: true, completion: nil)
  }
}

...

Обратите внимание: если сохранение занимает слишком много времени, ваш пользовательский интерфейс может стать неуклюжим, поскольку основной поток будет заблокирован во время сохранения. В этом случае вам, возможно, придется попробовать другую логику сохранения.

Еще одна вещь, о которой вам нужно быть осторожнее, - это то, как вы показываете / скрываете панель инструментов. Вы дважды вызываете navigationController?.setToolbarHidden() в одном и том же методе, чтобы показать, а затем скрыть его. Однако вам необходимо принять во внимание то, что обновления пользовательского интерфейса не выполняются мгновенно, а ставятся в очередь в основном потоке для выполнения после возврата из вашего метода. Таким образом, если оставить их как есть, панель инструментов не будет отображаться / скрываться.

На самом деле это не ответ, но это то, что вам нужно учитывать при реализации.

1
halileohalilei 3 Янв 2018 в 11:49