gpt4 book ai didi

ios - UIDeviceOrientationDidChangeNotification 多次调用

转载 作者:行者123 更新时间:2023-11-29 03:13:40 26 4
gpt4 key购买 nike

当设备改变方向时,UIDeviceOrientationDidChangeNotification 会多次调用。我不确定为什么会发生这种情况或如何解决它。

我想做的是保持 scrollview 的 contentoffset 不变,这样当用户旋转屏幕时,应用程序会保持他们所在的页面。

奇怪的是,当我第一次旋转屏幕时,代码按照我想要的方式执行。但之后每次代码都会执行多次,最终 contentoffset 被设置为 0。

这是我的。

- (void)loadView {

//some code that sizes itself depending on the current orientation
//WILL BE CALLED AFTER EVERY ORIENTATION CHANGE

}

- (void)viewDidLoad {

//begin generating messages
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];


[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];

//if is portrait and was landscape
if (orientation==1 && temp==2) {
int cal = offsetHolder.x/screenframe.size.height;
offsetHolder.x = cal * screenframe.size.width;
ScrollView.contentOffset = offsetHolder;
}

//if is landscape and was portrait
if (orientation==2 && temp==1) {
int cal = offsetHolder.x/screenframe.size.width;
offsetHolder.x = cal * screenframe.size.height;
ScrollView.contentOffset = offsetHolder;
}


}

在方向更改时,我更改“intorientation”的值,然后调用loadview来更改 View 的大小。然后我调用 viewdidload 来获取正确的 contentoffset

- (void) orientationChanged:(NSNotification *)note {

CGRect screenframe = [[UIScreen mainScreen] bounds];

//holding the current offset
offsetHolder = ScrollView.contentOffset;

if ([[UIDevice currentDevice] orientation] == 1 || [[UIDevice currentDevice] orientation] == 0 || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) {
temp=orientation;
orientation = 1;

[self loadView];
[self viewDidLoad];
}

else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationFaceDown || [[UIDevice currentDevice] orientation] == UIDeviceOrientationFaceUp){

temp=orientation;
}

else{
temp=orientation;
orientation = 2;
[self loadView];
[self viewDidLoad];
}
}

编辑:

我发现了问题。我正在做的是创建 self.view 的另一个实例,而不是覆盖这个实例。有没有一种简单的方法可以销毁此 View 并重新初始化它?

编辑2:

已找到修复方法。我按照 jsds 的指示停止调用 loadview 和 viewdidload 。相反,我将 loadview 中的所有代码移至我从 loadview 调用的另一个函数中。所有这些代码所做的就是实例化 UI (initview) 对象并根据方向将它们放置在正确的位置。

然后我创建另一个函数来从 View 中删除所有 subview 。然后,在方向更改时,我调用此函数和 initview 来销毁所有 subview ,然后在方向更改时重新创建它们。

最佳答案

UIDeviceOrientation 基本上有 6 种不同的状态,分别是两种纵向、两种横向、正面朝上和正面朝下。因此,假设当您将设备从平面位置拿起到垂直位置时,将触发通知。您可以使用宏UIDeviceOrientationIsValidInterfaceOrientation

来过滤面朝上、面朝下和未知状态
UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];

// Ignore changes in device orientation if unknown, face up, or face down.
if (!UIDeviceOrientationIsValidInterfaceOrientation(currentOrientation)) {
return;
}

如果您仍然发现通知被多次触发,恐怕您可能需要使用带有标志的自定义逻辑来检查之前和当前的值。

在我的例子中,由于我使用的是响应式(Reactive) cocoa 框架,因此以下代码适用于我:

如果(IS_IPAD){
@弱化( self );
[[[[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIDeviceOrientationDidChangeNotification object:nil]
takeUntil:[self rac_willDeallocSignal]]
map :^ id(NSNotification *通知){
返回@([[UIDevice currentDevice]方向]);
}]
过滤器:^BOOL(NSNumber * deviceOrientationNumber){
UIDeviceOrientation currentOrientation = [deviceOrientationNumber integerValue];
//我们忽略 UIDeviceOrientationUnknown, UIDeviceOrientationFaceUp 和 UIDeviceOrientationFaceDown
返回 UIDeviceOrientationIsValidInterfaceOrientation(当前方向);
}]
distinctUntilChanged]
subscribeNext:^(id x) {
@strongify( self );
//在这里做点什么...
}];
}

这里的 distinctUntilChanged 方法确保仅当方向更改为新的有效值时才触发代码。

关于ios - UIDeviceOrientationDidChangeNotification 多次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21943767/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com